SORU
9 AĞUSTOS 2009, Pazar


Çok kötü::lexical_cast artırmak performans

Windows XP SP3. Core 2 Duo 2.0 GHz. Destek buluyorum::lexical_cast performans son derece yavaş olması. Kodu hızlandırmak için yollar bulmak istedim. Visual c 2008 /O2 iyileştirmeleri kullanarak ve java 1.6 ve python 2.6.2 ile karşılaştırıldığında aşağıdaki sonuçlara bakın.

Tamsayı döküm:

c  : 
std::string s ;
for(int i = 0; i < 10000000;   i)
{
    s = boost::lexical_cast<string>(i);
}

java:
String s = new String();
for(int i = 0; i < 10000000;   i)
{
    s = new Integer(i).toString();
}

python:
for i in xrange(1,10000000):
    s = str(i)

Çıktığım zamanlar

c : 6700 milisaniye

java: 1178 milisaniye

python: 6702 milisaniye

c ve python gibi yavaş ve java daha 6 kat daha yavaş.

Çift döküm:

c  :
std::string s ;
for(int i = 0; i < 10000000;   i)
{
    s = boost::lexical_cast<string>(d);
}

java:
String s = new String();
for(int i = 0; i < 10000000;   i)
{
    double d = i*1.0;
    s = new Double(d).toString();
}

python:
for i in xrange(1,10000000):
    d = i*1.0
    s = str(d)

Çıktığım zamanlar

c : 56129 milisaniye

java: 2852 milisaniye

python: 30780 milisaniye

Çift c aslında python yarısı hızı ve 20 kat daha yavaş java çözüm daha!!. Boost iyileştirilmesi üzerinde herhangi bir fikir::lexical_cast performans? Bu zavallı stringstream olarak uygulanmasından mı yoksa boost kütüphaneleri kullanarak performans genel 10x bir düşüş bekleyebiliriz.

CEVAP
9 AĞUSTOS 2009, Pazar


2012-04-11 düzenleyin

rve oldukça haklı lexical_cast performansı ile ilgili bir bağlantı sağlayan yorumladı:

http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast/performance.html

Erişim 1.49, ama benim kod daha hızlı yapmak hatırlıyorum artırmak için şu anda eski bir sürüm yok. Sanırım bu yüzden:

  1. aşağıdaki cevap hala geçerli öğrenme amaçlı
  2. muhtemelen bir optimizasyon bir yere tanıtılan iki sürüm arasında (arayacağım) vardı
  3. bu destek hala daha iyi ve daha iyi oluyor demek ki

Orijinal cevap

Sadece Barry ve Motti mükemmel cevaplar bilgi eklemek için:

Bazı arka plan

Unutmayın Destek lütfen bu gezegendeki en iyi C geliştiricileri tarafından yazılmış ve aynı en iyi geliştiriciler tarafından yapılmıştır. Eğer lexical_cast çok yanlış olsaydı, birisi ya da kod ile eleştiri ya da kütüphane kesmek olurdu.

lexical_castbakmamışsın'In gerçek bir değeri var . sanırım

Elma ve portakal karşılaştırarak.

Java, Java bir dizeye bir tamsayı döküm. Karakter dizisi bahsetmiyorum dikkat edeceğiz, ya da kullanıcı tanımlı bir dize. Çok-kullanıcı tanımlı tamsayı bahsetmiyorum dikkat edeceğiz. Java ve Java Dize Tamsayı sıkı sıkı bahsediyorum.

Python, daha fazla veya daha az aynı şeyi yapıyorsun.

Diğer mesajları da dediği gibi, özünde, sprintf Java ve Python eşdeğeri (veya 11 ** daha az standart) kullanıyorsunuz.

C , çok güçlü bir döküm kullanıyorsunuz. Uzama ve ham hız performans anlamında (eğer hız isterseniz, belki de sprintf daha uygun olurdu) güçlü değil, ama bu anlamda güçlü.

Elma karşılaştırma.

Eğer Integer.toString Java yöntemi karşılaştırmak istiyorsanız, o zaman ya sprintf C veya C ile karşılaştırmak gerekir ostream imkanı.

C stream çözüm lexical_cast ve daha az genişletilebilir oldukça daha 6 kat daha hızlı oLurdu (Benim g):

inline void toString(const int value, std::string & output)
{
   // The largest 32-bit integer is 4294967295, that is 10 chars
   // On the safe side, add 1 for sign, and 1 for trailing zero
   char buffer[12] ;
   sprintf(buffer, "%i", value) ;
   output = buffer ;
}

C sprintf çözüm (benim g) lexical_cast 'den 8 kat daha hızlı ama daha az güvenli olacaktır:

inline void toString(const int value, char * output)
{
   sprintf(output, "%i", value) ;
}

Her iki çözüm gibi hızlı ya da daha hızlı Java çözüm (kendi verilerine göre).

Armutları karşılaştırmak.

Eğer bir C karşılaştırmak istiyorsanız lexical_cast o zaman bu Java sahte kod ile karşılaştırmak gerekir:

Source s ;
Target t = Target.fromString(Source(s).toString()) ;

Kaynak ve Hedef her ne istiyorsan, yerleşik boolean veya şablonlarını C mümkün olan int gibi türleri de dahil olmak.

Kullanildigini? Bu kirli bir kelime var mı?

Aynı kodlayıcı tarafından yazılmış, özel sorunlar için genel çözümler genellikle özel çözümleri kendi özel sorunları için yazılmış daha yavaştır. hayır, ama iyi bilinen bir maliyeti vardır:

Mevcut durumda, bir naif bakış açısı, lexical_cast kullanır akım tesisleri dönüştürmek bir tip A içine bir dize akışı, ve daha sonra bu dize akışı içine bir tür B.

Bunun anlamı o kadar nesne olabilir çıkış akımı ve giriş akışı, yapabileceksiniz kullanın lexical_cast, dokunmadan herhangi bir tek satırlık bir kod.

, lexical_cast kullanım alanları nelerdir?

Sözlü döküm ana kullanır:

  1. Kullanım kolaylığı (her şey için çalışır C bir döküm bir değeri olan hey!)
  2. Detayları ile uğraşmak istemiyorsun gibi türleri parametrize nerede şablonu ağır kodu ile birleştirme ve türleri bilmek istemezsin.
  3. Aşağıda göstereceğim gibi temel şablon bilginiz varsa hala potansiyel olarak nispeten verimli,,

Nokta 2 tane var anlamına gelir, çünkü burada çok önemlidir çok, ve tek bir arayüz/başka bir tür eşit veya benzer bir değer haline türünde bir değer atama fonksiyonu.

Bu kaçırdın asıl nokta, bu performans açısından maliyeti noktasıdır.

Ama çok slooooooowwww!

İsterseniz çiğ hız performansı, unuttun mu ile ilgili C , ve bir sürü imkanları tanıtıcı dönüşüm verimli, ve hala, devam et lexical_cast kolay kullanım özelliği.

Bana birkaç dakika lexical_cast kaynağına bak ve kalıcı bir çözüm ile gelip aldı. C kodu için aşağıdaki kodu ekleyin:

#ifdef SPECIALIZE_BOOST_LEXICAL_CAST_FOR_STRING_AND_INT

namespace boost
{
   template<>
   std::string lexical_cast<std::string, int>(const int &arg)
   {
      // The largest 32-bit integer is 4294967295, that is 10 chars
      // On the safe side, add 1 for sign, and 1 for trailing zero
      char buffer[12] ;
      sprintf(buffer, "%i", arg) ;
      return buffer ;
   }
}

#endif

Etkinleştirerek, bu uzmanlık lexical_cast için dizeleri ve değer vermez (tanımlayarak makro SPECIALIZE_BOOST_LEXICAL_CAST_FOR_STRING_AND_INT), kodum gitti 5 kez daha hızlı benim g derleyici anlamına göre veri, performans olmalı java'ya benzer.

Ve benim kod artırmak ve uzaktan etkili ve 32-bit doğru bir sürümünü yazmak bakarak 10 dakika sürdü. Ve biraz çalışma ile, muhtemelen daha hızlı ve daha güvenli (eğer doğrudan std::string dahili bellek yazma erişimi olsaydı, geçici dış tampon, örneğin önüne geçebiliriz) olabilir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • arnejann

    arnejann

    3 Kasım 2007
  • iZAPPA

    iZAPPA

    16 Temmuz 2010
  • stokelycalm

    stokelycalm

    28 Aralık 2010