, 1 min read
Parsing numbers in C++: streams, strtod, from_chars
When programming, we often want to convert strings (e.g., “1.0e2”) into numbers (e.g., 100). In C++, we have many options. In a previous post, I reported that it is an expensive process when using the standard approach (streams).
Many people pointed out to me that there are faster alternatives. In C++, we can use the C approach (e.g., strtod). We can also use the from_chars
function. The net result is slightly more complicated code.
do {
number = strtod(s, &end);
if(end == s) break;
sum += number;
s = end;
} while (s < theend);
I use long strings (100,000 numbers), and the GNU GCC 8.3 compiler on an Intel Skylake processor.
integers (stream) | 200 MB/s |
---|---|
integers (from_chars) | 750 MB/s |
floats (stream) | 50 MB/s |
floats (strtod) | 90 MB/s |
We see that for integers, the from_chars
function almost four times faster than the stream approach. Unfortunately my compiler does not support the from_chars
function when parsing floating-point numbers. However, I can rely on the similar C function (strtod). It is nearly twice as fast as the floating-point approach. Even so, it still costs nearly 38 cycles per byte to parse floating-point numbers.
For each floating-point number, there are almost 10 branch misses in my tests, even though I generate numbers using a fixed format. The number of branch misses is nearly the same whether we use a C++ stream or the C function.