This function reads an array of doubles from a string:
vector<double> parseVals(string& str) {
stringstream ss(str);
vector<double> vals;
double val;
while (ss >> val) vals.push_back(val);
return vals;
}
When called with a string containing 1 million numbers, the function takes 7.8 seconds to execute (Core i5, 3.3GHz). This means that 25000 CPU cycles are spent to parse ONE NUMBER.
user315052 has pointed out that the same code runs an order of magnitude faster on his system, and further testing has shown very large performance differences among different systems and compilers (also see user315052's answer):
1. Win7, Visual Studio 2012RC or Intel C++ 2013 beta: 7.8 sec
2. Win7, mingw / g++ 4.5.2 : 4 sec
3. Win7, Visual Studio 2010 : 0.94 sec
4. Ubuntu 12.04, g++ 4.7 : 0.65 sec
I have found a great alternative in the Boost/Spirit library. The code is safe, concise and extremely fast (0.06 seconds on VC2012, 130x faster than stringstream).
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
vector<double> parseVals4(string& str) {
vector<double> vals;
qi::phrase_parse(str.begin(), str.end(),
*qi::double_ >> qi::eoi, ascii::space, vals);
return vals;
}
Although this solves the problem from the practical standpoint, i would still like to know why the performance of stringstream is so inconsistent. I profiled the program to identify the bottleneck, but the STL code looks like gibberish to me. Comments from anybody familiar with STL internals would be much appreciated.
PS: Optimization is O2 or better in all of the above timings. Neither instantiation of stringstream nor the reallocation of vector figure in the program profile. Virtually all of the time is spent inside the extraction operator.