升压很差:: lexical_cast的表现 [英] Very poor boost::lexical_cast performance

查看:157
本文介绍了升压很差:: lexical_cast的表现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的Windows XP SP3。酷睿2 2.0GHz的。
我发现了boost :: lexical_cast的性能是非常慢。想找出办法,以加快code。在VISUAL C ++ 2008中使用/ O2优化和与Java 1.6和Python 2.6.2我看到下面的结果对比。

Windows XP SP3. Core 2 Duo 2.0 GHz. I'm finding the boost::lexical_cast performance to be extremely slow. Wanted to find out ways to speed up the code. Using /O2 optimizations on visual c++ 2008 and comparing with java 1.6 and python 2.6.2 I see the following results.

整数铸造:

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)

我看到的时间是

C ++:6700毫秒

c++: 6700 milliseconds

Java的:1178毫秒

java: 1178 milliseconds

蟒蛇:6702毫秒

C ++是Python作为慢,比Java更慢的6倍。

c++ is as slow as python and 6 times slower than java.

双铸造:

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)

我看到的时间是

C ++:56129毫秒

c++: 56129 milliseconds

Java的:2852毫秒

java: 2852 milliseconds

蟒蛇:30780毫秒

因此​​,对于双打C ++实际上是蟒蛇的速度的一半,比Java解决方案慢20倍!。提高了boost :: lexical_cast的性能有任何想法?从穷人stringstream的实现这是否干,还是会有使用升压库中表现一般的10倍下降。

So for doubles c++ is actually half the speed of python and 20 times slower than the java solution!!. Any ideas on improving the boost::lexical_cast performance? Does this stem from the poor stringstream implementation or can we expect a general 10x decrease in performance from using the boost libraries.

推荐答案

RVE 相当正确地评论了关于lexical_cast的性能,提供了一个链接:

Edit 2012-04-11

rve quite rightly commented about lexical_cast's performance, providing a link:

<一个href=\"http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast/performance.html\">http://www.boost.org/doc/libs/1_49_0/doc/html/boost_lexical_cast/performance.html

我用不上,现在提高1.49,但我记得让我的code上的旧版本快。所以我想:

I don't have access right now to boost 1.49, but I do remember making my code faster on an older version. So I guess:


  1. 下面的答案仍然有效(如果只是为了学习目的)

  2. 有可能是两个版本之间的某处引入一个优化(我会搜索该)

  3. 这意味着提振仍是越来越好

我想补充信息对巴里和Motti出色的答案:

Original answer

Just to add info on Barry's and Motti's excellent answers:

请记住升​​压是这个星球上最好的C ++开发人员编写的,且由同一最好的开发人员审查。如果的lexical_cast 真的错了,会有人砍死图书馆要么批评或code。

Please remember Boost is written by the best C++ developers on this planet, and reviewed by the same best developers. If lexical_cast was so wrong, someone would have hacked the library either with criticism or with code.

我猜你错过了点的lexical_cast 的真正价值......

I guess you missed the point of lexical_cast's real value...

在Java中,你是铸造一个整数到Java String类型。你会注意到,我不是在谈论一个字符数组或用户定义的字符串。你会注意到,太,我不是在谈论你的用户定义的整数。我说的是Java的严格整数和严格的Java的String。

In Java, you are casting an integer into a Java String. You'll note I'm not talking about an array of characters, or a user defined string. You'll note, too, I'm not talking about your user-defined integer. I'm talking about strict Java Integer and strict Java String.

在Python中,你或多或少做同样的。

In Python, you are more or less doing the same.

正如其他职位说,你是在本质上,使用的sprintf 的Java和Python当量(或更少的标准 itoa )。

As said by other posts, you are, in essence, using the Java and Python equivalents of sprintf (or the less standard itoa).

在C ++中,您使用的是一个非常强大的演员。在原始性能速度感不强(如果你想要的速度,也许的sprintf 会更适合),但在可扩展性的意义强大。

In C++, you are using a very powerful cast. Not powerful in the sense of raw speed performance (if you want speed, perhaps sprintf would be better suited), but powerful in the sense of extensibility.

如果要比较一个Java Integer.toString 方法,那么你应该把它比拟无论是C 的sprintf 或C ++ 的ostream 设施。

If you want to compare a Java Integer.toString method, then you should compare it with either C sprintf or C++ ostream facilities.

C ++的流解决方案将是6倍以上的lexical_cast 更快(在我的G ++),相当不易伸长:

The C++ stream solution would be 6 times faster (on my g++) than lexical_cast, and quite less extensible:

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 解决方案将是8倍,比的lexical_cast 更快(在我的G ++),但少了很多安全

The C sprintf solution would be 8 times faster (on my g++) than lexical_cast but a lot less safe:

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

这两种解决方案或者是比你的Java解决方案的速度或更快(根据您的数据)。

Both solutions are either as fast or faster than your Java solution (according to your data).

如果要比较一个C ++ 的lexical_cast ,那么你应该将其与该Java伪code比较:

If you want to compare a C++ lexical_cast, then you should compare it with this Java pseudo code:

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

源和目标是任何你想要的类型,包括内置的类型,如布尔 INT ,其中有可能在C ++,因为模板。

Source and Target being of whatever type you want, including built-in types like boolean or int, which is possible in C++ because of templates.

没有,但它有一个众所周知的成本:当在同一codeR写的,具体问题的通解通常比他们的具体问题写具体的解决方案更慢

No, but it has a well known cost: When written by the same coder, general solutions to specific problems are usually slower than specific solutions written for their specific problems.

在目前的情况下,在一个天真的观点,的lexical_cast 将使用流设施,从一个类型转换 A 成字符串流,然后从这个字符串流成键入 B

In the current case, in a naive viewpoint, lexical_cast will use the stream facilities to convert from a type A into a string stream, and then from this string stream into a type B.

这意味着,只要你的对象可以输出到一个流,并从输入流,你就可以使用的lexical_cast 就可以了,没有碰任何单行code的。

This means that as long as your object can be output into a stream, and input from a stream, you'll be able to use lexical_cast on it, without touching any single line of code.

词法铸造的主要用途是:

The main uses of lexical casting are:


  1. 易于使用(嘿嘿,一个C ++演员,其中的一切是一个值的作品!)

  2. 将其与模板重code,其中的类型参数化的,因此你不想处理的细节,你不想知道的类型组合。

  3. 还有可能比较有效,如果你有基本的模板知识,下面我会展示

点2是非常非常重要的位置,因为这意味着我们有一个且只有一个接口/功能投下类型的值转换成另一种类型的相同或类似的价值。

The point 2 is very very important here, because it means we have one and only one interface/function to cast a value of a type into an equal or similar value of another type.

这是你错过了真正的问题,这就是,在性能方面成本的地步。

This is the real point you missed, and this is the point that costs in performance terms.

如果你想生高速性能,还记得你处理C ++,而且你有很多的设施,以有效地处理转换,仍然,保持的lexical_cast 易于使用的功能。

If you want raw speed performance, remember you're dealing with C++, and that you have a lot of facilities to handle conversion efficiently, and still, keep the lexical_cast ease-of-use feature.

我花了几分钟看lexical_cast的来源,并配备了一个可行的解决方案。添加到您的C ++ code以下code:

It took me some minutes to look at the lexical_cast source, and come with a viable solution. Add to your C++ code the following code:

#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

通过启用lexical_cast的字符串和整数的这种专业化(通过定义宏 SPECIALIZE_BOOST_LEXICAL_CAST_FOR_STRING_AND_INT ),我的code去5时间快上我的G ++编译器,这意味着根据您的数据,其性能应类似于Java的。

By enabling this specialization of lexical_cast for strings and ints (by defining the macro SPECIALIZE_BOOST_LEXICAL_CAST_FOR_STRING_AND_INT), my code went 5 time faster on my g++ compiler, which means, according to your data, its performance should be similar to Java's.

和我花了10分钟看助推code,谱写远程高效和正确的32位版本。并与一些工作,它也许可以走得更快,更安全(如果我们不得不在的std ::字符串内部缓冲区直接写访问,我们能够避免一个临时的外部缓冲器,用于例子)。

And it took me 10 minutes of looking at boost code, and write a remotely efficient and correct 32-bit version. And with some work, it could probably go faster and safer (if we had direct write access to the std::string internal buffer, we could avoid a temporary external buffer, for example).

这篇关于升压很差:: lexical_cast的表现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆