C++ 07 Feb 2010 15:41:15
C++ Convert Int to String Speed
(There is also an opposite string-to-int performance test.)
(Updated 2011-02-05: Added a hand-made function as baseline; re-run all tests, and with new clang++ from svn)
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:
- naive loop into a std::string
- 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.4.1, and clang++ from svn.
Tests were run for converting 100000 integers in the range -50000 to 50000. The result for a hand-made naive function 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…
Windows: MSVC++ 2010 Express
- Compiler: MSVC++ 2010 _SECURE_SCL=0
- Arch: Windows 7 64 bit, 1.60GHz Core i7 Q720, 8 GiB RAM
Linux: GNU g++ 4.4.1
- Compiler: GNU g++ 4.4.1 -std=c++0x -O3
- Arch: Linux 2.6.27 x86_64, 2.66GHz Xeon, 8 GiB RAM
Linux: LLVM clang++
- Compiler: clang++ 2.9 (trunk 124900) -std=c++0x -O3
- Arch: Linux 2.6.27 x86_64, 2.66GHz Xeon, 8 GiB RAM
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.
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?
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)
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.
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
on 25 Mar 2010 at 14:54:46 6.Jeff said …
How about Qt? They generally have things optimized pretty well.
on 20 Jun 2010 at 23:39:19 7.Arash Partow said …
Have you considered including StrTk in your listings?
The tests used in that library are a little more extensive.
http://www.codeproject.com/KB/recipes/Tokenizer.aspx
on 22 Nov 2010 at 10:25:20 8.QbProg said …
Hello there,
I’m just converting my old int->string routines using Karma :)
A little question:
i need to implement double->string and
generate(Buf, double_ , d);
works well.
Is there a quick way to specify the number of decimals?
I was using
printf (“%0.3f”, myNumber)
to get 3 decimals numbers.
thank you!
on 23 Nov 2010 at 03:16:25 9.Tino Didriksen said …
To get printf() formatting, I’d suggest using Boost Format. Whether that uses the fast Karma implementation, I dunno, but can read the documentation or ask Freenode’s #boost.
on 08 Jul 2011 at 00:15:40 10.Roger said …
@6, Jeff:
Unfortunately Qt doesn’t have anything optimized. Qt is a library for easy and safe coding, it is far from optimized for speed. If anything Qt calls are MUCH slower than anything that’s mentioned above. Qt function calls are anywhere from 2x up to 10x slower than the examples above, depending on what function you use.
If you don’t believe me, do the tests yourself.
Also undocumented is the speed of some Qt functions. For examples from the QString class, the functions to convert to QByteArray.
::toLatin1() is actually the fastest, followed by ::toAscii() and the slowest being ::toLocal8Bit().
Qt has a lot, LOT of performance problems. If you’re only writing applications that execute 20function calls a second, Qt is great because it allows for agile development. However if you’re handling applications that execute millions of function calls every second, containing a few Qt calls in each of those functions, the performance problems become visible.
on 17 Apr 2012 at 21:55:03 11.Joe said …
Hi, can you show source code, on which you tested speed of conversion from int to string?
on 17 Apr 2012 at 22:03:45 12.Tino Didriksen said …
It’s already shown in the post where it says “Source for the test is at speed-convert-int-to-string.cpp with cycle.h.”
( http://tinodidriksen.com/uploads/code/cpp/speed-convert-int-to-string.cpp + http://tinodidriksen.com/uploads/code/cpp/cycle.h )
on 19 Sep 2015 at 17:18:28 13.Robert said …
UPD: I’ve performed tests on my system, adding C++11’s std::to_string into the picture. Used clang 3.4.1 with -O3 for all tests.
The absolute winner (with avg 10345251 ticks) is a “naive (new string)” implementation. Assuming it’s ratio as 1, other competitors arranged as follows (from faster to slower):
lexical_cast: 2
karma: 2
sprintf: 5-6
to_string: 6
strstream: 10-15
stringstream: 12-17