首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >c++ stringstream太慢了,怎么提速?

c++ stringstream太慢了,怎么提速?
EN

Stack Overflow用户
提问于 2011-04-29 18:26:10
回答 4查看 30.7K关注 0票数 23

可能重复:

Fastest way to read numerical values from text file in C++ (double in this case)

代码语言:javascript
运行
复制
#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

更新:删除底套接字,env: win7+vc10

EN

回答 4

Stack Overflow用户

发布于 2011-04-29 21:02:24

C/C++文本到数字的格式化非常慢。流非常慢,但即使是C数字解析也很慢,因为很难将其精确到最后一位精度。

在一个生产应用程序中,读取速度很重要,并且已知数据最多有三个十进制数字,没有科学记数,我通过手工编写一个仅处理符号、整数部分和任意数量的小数的浮动解析函数,获得了巨大的改进(这里的“大量”,我指的是比strtod快10倍)。

如果你不需要指数,并且这个函数的精度足够高,这是一个解析器的代码,类似于我之前写的那个。在我的PC上,它现在比strtod快6.8倍,比sstream快22.6倍。

代码语言:javascript
运行
复制
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;
}
票数 11
EN

Stack Overflow用户

发布于 2011-04-29 20:16:33

字符串流很慢。非常非常慢。如果您正在编写对大型数据集起作用的、对性能至关重要的内容(例如,在游戏期间更改级别后加载资产),则不要使用字符串流。为了提高性能,我推荐使用老的C库解析函数,尽管我不能说它们与boost spirit之类的函数相比有什么不同。

然而,与c库函数相比,字符串流是非常优雅,可读和可靠的,所以如果你正在做的不是性能问题,我建议坚持使用流。

票数 6
EN

Stack Overflow用户

发布于 2011-04-29 18:30:18

一般来说,如果你需要速度,考虑这个库:

http://www.fastformat.org/

(我不确定它是否包含将字符串或流转换为其他类型的函数,因此它可能不会回答您当前的示例)。

为了记录在案,请注意,您在这里将苹果与橙子进行比较。strtod()是一个简单的函数,只有一个目的(将字符串转换为双精度),而stringstream是一种复杂得多的格式化机制,它远远没有针对特定的目的进行优化。更公平的比较是将stringstream与sprintf/sscanf系列函数进行比较,后者比strtod()慢,但仍然比stringstream快。我不太确定stringstream的设计比sprintf/sscanf慢的原因是什么,但看起来就是这样。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5830868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档