Ç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
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:
- aşağıdaki cevap hala geçerli öğrenme amaçlı
- muhtemelen bir optimizasyon bir yere tanıtılan iki sürüm arasında (arayacağım) vardı
- 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_cast
bakmamış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:
- Kullanım kolaylığı (her şey için çalışır C bir döküm bir değeri olan hey!)
- Detayları ile uğraşmak istemiyorsun gibi türleri parametrize nerede şablonu ağır kodu ile birleştirme ve türleri bilmek istemezsin.
- 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.
C standart iostreams için düşük perfor...
Neden performans için iç içe ağırlıkla...
MapKit Apple Haritalar ile kötü perfor...
&Quot;en iyi performans" için depo...
Sanal fonksiyonlar ve performans - C ...