Possible Duplicate:
Fastest way to read numerical values from text file in C++ (double in this case)
#include <ctime> #include <cstdlib> #include <string> #include <sstream> #include <iostream> #include <limits> using namespace std; static const double NAN_D = numeric_limits<double>::quiet_NaN(); void die(const char *msg, const char *info) { cerr << "** error: " << msg << " \"" << info << '\"'; exit(1); } double str2dou1(const string &str) { if (str.empty() || str[0]=='?') return NAN_D; const char *c_str = str.c_str(); char *err; double x = strtod(c_str, &err); if (*err != 0) die("unrecognized numeric data", c_str); return x; } static istringstream string_to_type_stream; double str2dou2(const string &str) { if (str.empty() || str[0]=='?') return NAN_D; string_to_type_stream.clear(); string_to_type_stream.str(str); double x = 0.0; if ((string_to_type_stream >> x).fail()) die("unrecognized numeric data", str.c_str()); return x; } int main() { string str("12345.6789"); clock_t tStart, tEnd; cout << "strtod: "; tStart=clock(); for (int i=0; i<1000000; ++i) double x = str2dou1(str); tEnd=clock(); cout << tEnd-tStart << endl; cout << "sstream: "; tStart=clock(); for (int i=0; i<1000000; ++i) double x = str2dou2(str); tEnd=clock(); cout << tEnd-tStart << endl; return 0; }
strtod: 405
sstream: 1389
update: remove undersocres, env: win7+vc10
stringstreams are primarily there for convenience and type-safety, not speed. The stream will collect the input and then eventually call strtold for the conversion. Makes it hard to be any faster!
The stringstream class in C++ allows a string object to be treated as a stream. It is used to operate on strings. By treating the strings as streams we can perform extraction and insertion operation from/to string just like cin and cout streams.
C/C++ text to number formatting is very slow. Streams are horribly slow but even C number parsing is slow because it's quite difficult to get it correct down to the last precision bit.
In a production application where reading speed was important and where data was known to have at most three decimal digits and no scientific notation I got a vast improvement by hand-coding a floating parsing function handling only sign, integer part and any number of decimals (by "vast" I mean 10x faster compared to strtod
).
If you don't need exponent and the precision of this function is enough this is the code of a parser similar to the one I wrote back then. On my PC it's now 6.8 times faster than strtod and 22.6 times faster than sstream.
double parseFloat(const std::string& input) { const char *p = input.c_str(); if (!*p || *p == '?') return NAN_D; int s = 1; while (*p == ' ') p++; if (*p == '-') { s = -1; p++; } double acc = 0; while (*p >= '0' && *p <= '9') acc = acc * 10 + *p++ - '0'; if (*p == '.') { double k = 0.1; p++; while (*p >= '0' && *p <= '9') { acc += (*p++ - '0') * k; k *= 0.1; } } if (*p) die("Invalid numeric format"); return s * acc; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With