“解析”特定字符串的最快方法

fastest way to "parse" specific string

提问人:Nick 提问时间:7/14/2023 更新时间:7/14/2023 访问量:88

问:

我需要解析像这样的字符串,例如像 ."<double>,<double>,<char[12]>""12.34555,23.44343343,abcdef"

但是,我想让它尽可能快。


正如我们所知,它并不真正适用于 ,所以我只能看到选项是 或 。<charconv>doublestrtodsscanf

没有测试过,它似乎总是很慢,还包括内存分配。<iostreams>

另一个不错的选择是创建自己的函数 - 我尝试过但很难正确(与strtod<charconv>)

sscanf实施似乎很干净,但我不确定它会有多快。

如果代码适用于非 NULL 终止的字符串,则奖励将是,例如 .std::string_view

仅供参考,以下是代码:sscanf

#include <cstdio>
#include <cstring>

void scan(const char *s){
    double a = 0;
    double b = 0;
    char h[32];
    // fill, in order to see if it was parsed
    memset(h, 'x', 31); h[31] = '\0';

    sscanf(s, "%lf,%lf,%s", &a, &b, h);

    printf("%.4lf\t%.4lf\t%s\n", a, b, h);
}

int main() {
    scan("12.34555,23.44343343,abcdef");
    scan("12.34555,,abcdef");
    scan("12.34555,23.44343343,");
    scan("12.34555,23.44343343");
    scan("12.34555,");
    scan("12.34555");
    scan("");
    scan("boba");
}

为了加快速度,如果这有帮助,我也可以将其设置为固定的十进制数字,例如

"+12.12345678,-12.12345678,abcde1234512".

但是,如果传递了错误的字符串,代码需要能够检查它。

C++ 解析

评论

0赞 Some programmer dude 7/14/2023
如果您决定使用 type-unsafe 函数,请记住对尝试读取的字符串添加限制。否则,您迟早会遇到缓冲区溢出。sscanf
0赞 Some programmer dude 7/14/2023
为什么不简单地构建一个程序来尝试所有不同的可能性,在启用优化的情况下构建它,然后只是用函数的时序来尝试它呢?请记住尝试每个函数几千次以获得体面的平均值。
2赞 Some programmer dude 7/14/2023
或者先尝试简单幼稚的方法,如果你对时间有任何要求,那么你看看这是否是最大的瓶颈,只有当它是时,才尝试修复它。
2赞 Botje 7/14/2023
这样做是否有实际目的,或者只是精神手淫?像 zsv 这样的库使用 SIMD 操作解析 CSV。
1赞 Some programmer dude 7/14/2023
因此,而不是例如 用。否则,如果使用风险缓冲区溢出获得更大的代码,则当前代码会更大。sscanf("...,%s", ...)sscanf("..., %12s", ...)sscanf

答: 暂无答案