可能重复:
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
更新:删除undersocres,env:win7 + vc10
答案 0 :(得分:8)
C / C ++文本到数字格式很慢。流速度非常慢,但即使是C数字解析速度也很慢,因为很难将其校正到最后一个精度位。
在一个生产应用程序中,读取速度很重要,并且已知数据最多有三个十进制数字且没有科学记数法,我通过手工编写浮动解析函数只得到符号,整数部分和任何数字得到了巨大的改进小数(通过“大”我的意思比strtod
快10倍。)
如果你不需要exponent并且这个函数的精度足够,这就是一个类似于我当时写的解析器的代码。在我的电脑上,它现在比strtod快6.8倍,比sstream快22.6倍。
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;
}
答案 1 :(得分:4)
字符串流 慢。非常慢。如果您正在编写任何对大型数据集起作用的性能关键(例如在游戏过程中更改级别后加载资产),请不要使用字符串流。我建议使用旧的c库解析函数来提高性能,虽然我不能说它们与boost spirit之类的东西相比如何。
然而,与c库函数相比,字符串流非常优雅,可读且可靠,所以如果你所做的不是性能,我建议坚持使用流。
答案 2 :(得分:2)
一般来说,如果你需要速度,请考虑这个库:
(我不确定它是否包含将字符串或流转换为其他类型的函数,因此它可能无法回答您当前的示例。)
为了记录,请注意你在这里比较苹果和橘子。 strtod()
是一个简单的函数,只有一个目的(将字符串转换为double),而stringstream是一个更复杂的格式化机制,远未针对该特定目的进行优化。更公平的比较是将stringstream与sprintf / sscanf函数行进行比较,这些函数比strtod()
慢,但仍然比stringstream快。我不确定是什么让stringstream的设计比sprintf / sscanf慢,但看起来就是这种情况。
答案 3 :(得分:1)
您是否考虑过使用lexical_cast
来提升?
http://www.boost.org/doc/libs/1_46_1/libs/conversion/lexical_cast.htm
编辑:顺便说一下,clear()
应该是多余的。