将浮点数转换为字符串的最快 C++ 方法

vin*_*001 8 c++ floating-point formatting c++11

我遇到了将浮点数转换为字符串的问题,这to_string对我来说太慢了,因为我的数据可能涉及数百万个浮点数。

我已经有了如何快速写出这些数据的解决方案。

然而,在解决了那个问题之后,我很快意识到浮点数到字符串的转换产生了很大的影响。

那么,除了使用其他非标准库之外,还有其他想法或解决方案吗?

vit*_*aut 14

以下是一些将浮点数转换为十进制字符串表示的最快算法:

在撰写本文时,Dragonbox 是这些方法中最快的,其次是 Schubfach,然后是称为 Grisu-Exact 的 Grisu 变体(不要与 Grisu2 和 Grisu3 混淆),然后是 Ry?:

在此处输入图片说明

此处提供了 Dragonbox 的实现。它还包含在集成到高级格式化 API中的 {fmt} 库中。为了获得最大性能,您可以使用format_to堆栈分配的缓冲区,例如:

fmt::memory_buffer buf;
fmt::format_to(buf, "{}", 4.2);
// buf.data() returns a pointer to the formatted data & buf.size() gives the size
Run Code Online (Sandbox Code Playgroud)


dau*_*ama 2

想到的一个优化是不直接使用 to_string,它会在每次调用它时创建一个新字符串。您最终可能也会复制该字符串,这效率不高。

您可以做的是分配一个足够大的字符缓冲区来存储您需要的所有字符串表示形式,然后使用 printf

http://www.cplusplus.com/reference/cstdio/printf/

始终重复使用相同的缓冲区。如果将浮点数的精度限制为固定的小数位数,则可以计算浮点数在数组中表示的偏移量。

例如,如果我们只有一个值数组:

index = 1;
float f = value[index];
//corrresponding 6 chars float
const char* s = char_array[index*1];
//the representation will start at position 6, and it will be null terminated so you can use it as a string
Run Code Online (Sandbox Code Playgroud)

为了澄清起见,您的 char_array 将如下所示:

1.2000\02.4324\0...
Run Code Online (Sandbox Code Playgroud)