In my previous blog post, we noticed that concatenating strings was a mixed story depending on whether it were all real strings, or if you were mixing strings with integers and doubles. To understand the full picture we need to investigate how much of a penalty was taken because of the different way to convert the integer or double to a string. In this blog post, we will do exactly that.
There are a couple of ways you can convert an integer or double to string. A very known one is itoa. This method however is not part of the C++ standard and may not be available in all cases. Moreover there is no version to convert doubles. Because of these two reasons I have left this method out of the test as they should never be used!
The methods that I have been testing are:
The tested scenario’s consist of the following:
- Convert a single integer to a string. This is the simplest case as you don’t care about the format. Only in very rare cases you actually want to use stuffing in front of the integer.
- Convert a double to the default format of the method. Note that sprintf and to_string result in the same output (4 digits precision), while the stringstream uses scientific notification.
- Convert a double to a format with only 2 digits precision. The to_string method does not provide a way to change the format and is thus left out of this test.
All scenario’s involved convert a number 1,000,000 times. This has been repeated 100 times and the average of this was calculated. The results (in seconds) of all the tests are shown in the graph below:
Both the sprintf and to_string method are very close with the to_string pulling ahead by a tiny bit. The stringstream loses by a lot in all cases, but we have to add a note to this. This scenario assumes you only want to convert a single value and thus a new stringstream is created every single tmie. This results in a massive overhead, so what if we create the stringstream outside of the conversion, but instead only reset the value of the buffer.
When doing this, the stringstream is on par with the other methods except for the fixed format of the double value.
Does this mean that the good old sprintf is still the unbeaten champion and you should use it? Even though sprintf performed well in this test and the previous one, there are a couple of caveats to take into account. Sprintf writes the data to a char buffer, even though my tests have taken into account the conversion to an actual string, it still complicates some matters.
First of all, the format string is annoying if you want to concatenate many parts together. You could convert each part separately, but then you still need to concatenate those parts together, which just moves the problem.
My recommendation remains the same as before the tests, either use to_string or stringstream depending on your liking the use-case. The stringstream does have more overhead due to the creation of the actual stream, but writing parts to it is very convenient. The to_string method is handy if you just have a couple of parts to combine of which some happen to be a number. But be aware that if you don’t have any control over the format.