C++ 07 Feb 2010 15:41:15

C++ Convert Int to String Speed

(There is also an opposite string-to-int performance test.)

(Updated 2010-03-05 to compare speeds of reusing the string object versus not, and to add strstream and boost::spirit::karma tests.)

A performance benchmark of which method is faster of converting an integer to an std::string. The goal is ending up with an std::string representation of the input integer.

The tested methods are:

  • sprintf() into a char[] buffer, then std::string(buffer)
  • snprintf() into a char[] buffer, then std::string(buffer)
  • sprintf() into &std::string[0], and .resize() to fit
  • snprintf() into &std::string[0], and .resize() to fit
  • output to a std::stringstream, then std::string = stream.str()
  • as above, but reusing the stringstream object
  • std::strstream(&string[0]) then .resize(stream.pcount())
  • std::string = boost::lexical_cast<std::string>()
  • Boost.Spirit.Karma generate into a char[] buffer, then std::string(buffer)

Source for the test is at speed-convert-int-to-string.cpp with cycle.h.

The compilers are Microsoft Visual C++ 2010 Express as VC10 with _SECURE_SCL disabled, GNU g++ 4.3.2, and clang++ from svn.

Tests were run for converting 100000 integers in the range -50000 to 50000. The result for sprintf() is set as the baseline 100% and the other numbers is time spent relative to that.

Boost.Spirit.Karma is by far the fastest. It is also worth noting that reusing the string object makes the boost::lexical_cast solution slower, presumably because it ruins some optimization opportunities, so that is a case for checking whether reusing your objects really is faster…

VC++ 2010, Boost 1.42Percentage
sprintf char[] (reuse string)100.00%
sprintf char[] (new string)100.39%
snprintf char[] (reuse string)99.39%
sprintf &string[0] (reuse string)103.22%
snprintf &string[0] (reuse string)103.85%
stringstream (new stream, reuse string)502.88%
stringstream (new stream, new string)507.08%
stringstream (reuse stream, reuse string)278.56%
stringstream (reuse stream, new string)280.29%
strstream (reuse stream, internal buffer)611.35%
strstream (reuse stream, string buffer)621.25%
lexical_cast (reuse string)72.99%
lexical_cast (new string)69.72%
karma (reuse string)9.52%
karma (new string)10.17%
Fedora g++ 4.3.2, Boost 1.42Percentage
sprintf char[] (reuse string)100.00%
sprintf char[] (new string)124.93%
snprintf char[] (reuse string)99.21%
sprintf &string[0] (reuse string)103.14%
snprintf &string[0] (reuse string)105.37%
stringstream (new stream, reuse string)465.73%
stringstream (new stream, new string)471.35%
stringstream (reuse stream, reuse string)137.44%
stringstream (reuse stream, new string)131.40%
strstream (new stream, internal buffer)463.57%
strstream (reuse stream, string buffer)285.54%
lexical_cast (reuse string)96.26%
lexical_cast (new string)89.18%
karma (reuse string)32.79%
karma (new string)61.48%

The clang++ results are directly comparable with the g++ results; run on the same machine, and the sprintf() results deviate a mere 0.07%. clang++ could not compile the karma test, so that has been omitted.

clang++ 1.1 (trunk 97850), Boost 1.42Percentage
sprintf char[] (reuse string)100.00%
sprintf char[] (new string)129.02%
snprintf char[] (reuse string)99.57%
sprintf &string[0] (reuse string)102.61%
snprintf &string[0] (reuse string)103.92%
stringstream (new stream, reuse string)493.95%
stringstream (new stream, new string)499.09%
stringstream (reuse stream, reuse string)140.36%
stringstream (reuse stream, new string)133.43%
strstream (new stream, reuse string)506.13%
strstream (reuse stream, reuse string)279.85%
lexical_cast (reuse string)101.45%
lexical_cast (new string)95.87%

5 Responses to “C++ Convert Int to String Speed”

  1. on 10 Mar 2010 at 16:36:32 1.Sumant said …

    Quite interesting! The performance results on g++ (4.4.3) hold as they are shown only when optimizations are turned on. With the increasing level of optimizations (-O1, -O2, -O3), performance improves.

  2. on 10 Mar 2010 at 23:45:39 2.indranil banerjee said …

    Interesting. Surprised to see that lexical_cast performed better than stringstream, I thought the former was implemented using the latter?

    These results are quite contrary to the tests Sutter published back in 2001 http://www.gotw.ca/publications/mill19.htm. In those tests sprintf was the fastest, followed by strstream, stringstream & lexical_cast trailing. Have things changed so much?

  3. on 11 Mar 2010 at 11:04:34 3.Arzar said …

    I’m quite surprised to see lexical_cast performing this good too.

    Most of all, if you define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE the performance of lexical_cast increase even more. With MSCV10, I get ~30% instead of 70% !

    (for reference, I get ~15% with itoa)

  4. on 11 Mar 2010 at 11:36:09 4.Tino Didriksen said …

    It has since been specialized for the basic integer and floating point types: http://www.boost.org/doc/libs/release/boost/lexical_cast.hpp (search for lcast_put_unsigned and below).

    But for all other conversions, it is indeed dog slow. Just see http://tinodidriksen.com/2010/02/16/cpp-convert-string-to-int-speed/ where it trails by a huge margin.

  5. on 12 Mar 2010 at 04:48:23 5.Jeff said …

    You should try against ‘fast format’ too, for completeness – Matt Wilson’s no slouch.

    http://www.fastformat.org/performance.html

Subscribe to the comments through RSS Feed

Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word