在网上看到一篇文章redis fast_float, 其中介绍了快速浮点数转换库,下载源代码来试用了,真的比系统的strtod快出不少。
测试程序fast_float_test.cpp复制自上述文章,以防丢失。
#include <iostream>
#include <vector>
#include <chrono>
#include <cstring>
#include "fast_float/fast_float.h"
const char* test_strings[] = {
"3.14159", "2.7182818284", "1.0e10", "6.022e23",
"2.2250738585072014e-308",
"0.0", "123456789.987654321", "9.999999999999999e-10", "1e-10"
};
constexpr size_t NUM_STRINGS = std::size(test_strings);
constexpr int ITERATIONS = 1000000;
volatile double sink = 0.0; // 防止优化
int main(){
// 测试 strtod 性能
{
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < ITERATIONS; ++i){
for (size_t j = 0; j < NUM_STRINGS; ++j){
double val = strtod(test_strings[j], nullptr);
sink += val * 0; // 乘0避免溢出,但又用到 val 防止优化
}
}
auto end = std::chrono::high_resolution_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << "strtod total time: " << ms << " ms\n";
}
// 测试 fast_float 性能
{
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < ITERATIONS; ++i){
for (size_t j = 0; j < NUM_STRINGS; ++j){
double val;
auto res = fast_float::from_chars(test_strings[j], test_strings[j] + std::strlen(test_strings[j]), val);
if (res.ec == std::errc()){
sink += val * 0; // 同上,防止优化
}
}
}
auto end = std::chrono::high_resolution_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << "fast_float total time: " << ms << " ms\n";
}
return 0;
}
把源代码inclue目录下内容解压到当前目录。
编译和运行结果如下
g++ -std=c++20 -O3 -march=native fast_float_test.cpp -I .
./a.out
strtod total time: 363 ms
fast_float total time: 84 ms
注意,如果不想包含多个文件,fastfloat存储库还提供一个单独的头文件源代码, https://github.com/fastfloat/fast_float/releases/download/v8.0.2/fast_float.h 效果是一样的。
想要研究它的设计思想,可以查看论文。

1725

被折叠的 条评论
为什么被折叠?



