概述
描述
Boost.Charconv 在字符缓冲区和数字之间进行转换。它是一个小型库,包含两个重载函数来完成繁重的工作,以及几个支持性的枚举、结构体、模板和常量,特别关注性能和跨受支持开发环境的一致性。
我为什么要对这个库感兴趣? Charconv 是独立于区域设置的,非分配内存1,不抛出异常,并且仅需要最低限度的 C++ 11。它提供的功能类似于 std::printf
或 std::strtod
,但 性能大幅提升。如果您的工具链中没有标准库 <charconv>
,则可以使用此库代替它。目前,只有 GCC 11+ 和 MSVC 19.24+ 在其 <charconv>
实现中支持整数和浮点转换。
如果您正在使用这些编译器中的任何一个,Boost.Charconv 的性能至少与 <charconv>
一样好,甚至可能快几倍。请参阅:基准测试
1 可能发生分配内存的唯一极端情况是,您正在将字符串解析为 80 或 128 位 long double
或 __float128
,并且该字符串超过 1024 字节。
支持的编译器 / 操作系统
Boost.Charconv 在 Ubuntu、macOS 和 Windows 上使用以下编译器进行了测试
-
GCC 5 或更高版本
-
Clang 3.8 或更高版本
-
Visual Studio 2015 (14.0) 或更高版本
在 GitHub Actions 和 Drone 上进行了测试。
入门指南
B2
运行以下命令以克隆最新版本的 Boost 和 Charconv,准备 Boost.Build 系统以供使用,并使用 C++11 作为默认标准构建库
git clone https://github.com/boostorg/boost
cd boost
git submodule update --init
cd ..
./bootstrap
./b2 cxxstd=11
要安装开发环境,请运行
sudo ./b2 install cxxstd=11
cxxstd 的值必须至少为 11。 有关所有有效值,请参阅 cxxstd
下的 b2 文档。
__float128
和 std::float128_t
支持
如果使用 B2 或 CMake,构建系统将自动定义 BOOST_CHARCONV_HAS_QUADMATH
并在构建系统可以成功运行小型测试用例时链接它。 如果您正在使用另一个构建系统并且想要支持这些类型,则必须定义 BOOST_CHARCONV_HAS_QUADMATH
,并链接 libquadmath。
重要提示
|
libquadmath 仅在受支持的平台(例如,带有 x86、x86_64、PPC64 和 IA64 的 Linux)上可用。 |
依赖项
此库依赖于:Boost.Assert、Boost.Config、Boost.Core,以及可选的 libquadmath(见上文)。
基本用法示例
用法示例
#include <boost/charconv.hpp>
const char* buffer = "42";
int v = 0;
boost::charconv::from_chars_result r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc());
assert(v == 42);
char buffer[64];
int v = 123456;
boost::charconv::to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), v);
assert(r.ec == std::errc());
assert(!strncmp(buffer, "123456", 6)); // Strncmp returns 0 on match
API 参考
from_chars
from_chars 概述
from_chars
是一组函数,用于解析来自 [first, last)
的字符串,尝试根据指定的 chars_format
(如果适用)将字符串转换为 value
。 数字的解析是独立于区域设置的(例如,等效于“C”区域设置)。 from_chars
的结果是 from_chars_result
,成功时返回 ptr == last
和 ec == std::errc()
,失败时返回 ptr
等于最后一个解析的有效字符或下溢/溢出时的 last
,以及 ec == std::errc::invalid_argument
或 std::errc::result_out_of_range
。 from_chars
不要求字符序列以 null 结尾。
定义
namespace boost { namespace charconv {
struct from_chars_result
{
const char* ptr;
std::errc ec;
friend constexpr bool operator==(const from_chars_result& lhs, const from_chars_result& rhs) noexcept = default;
constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
}
template <typename Integral>
BOOST_CXX14_CONSTEXPR from_chars_result from_chars(const char* first, const char* last, Integral& value, int base = 10) noexcept;
template <typename Integral>
BOOST_CXX14_CONSTEXPR from_chars_result from_chars(boost::core::string_view sv, Integral& value, int base = 10) noexcept;
BOOST_CXX14_CONSTEXPR from_chars_result from_chars<bool>(const char* first, const char* last, bool& value, int base) = delete;
template <typename Real>
from_chars_result from_chars(const char* first, const char* last, Real& value, chars_format fmt = chars_format::general) noexcept;
template <typename Real>
from_chars_result from_chars(boost::core::string_view sv, Real& value, chars_format fmt = chars_format::general) noexcept;
// See note below Usage notes for from_chars for floating point types
template <typename Real>
from_chars_result from_chars_erange(const char* first, const char* last, Real& value, chars_format fmt = chars_format::general) noexcept;
template <typename Real>
from_chars_result from_chars_erange(boost::core::string_view sv, Real& value, chars_format fmt = chars_format::general) noexcept;
}} // Namespace boost::charconv
from_chars 参数
-
first
,last
- 指向要解析的有效范围的指针 -
sv
- 要解析的有效范围的字符串视图。 兼容 boost::core::string_view、std::string 和 std::string_view -
value
- 成功解析后输出存储的位置 -
base
(仅限整数)- 要使用的整数基数。 必须介于 2 和 36 之间(包含 2 和 36) -
fmt
(仅限浮点数)- 缓冲区的格式。 有关描述,请参阅 chars_format 概述。
from_chars_result
-
ptr
- 从from_chars
返回时,它是指向第一个与模式不匹配的字符的指针,如果所有字符都已成功解析,则为指向last
的指针。 -
ec
- 错误代码。from_chars
返回的值为
返回值 |
描述 |
|
成功解析 |
|
1) 将负数解析为无符号类型 2) 前导 3) 前导空格 4) 不兼容的格式(例如, |
|
1) 溢出 2) 下溢 |
-
operator==
- 比较 ptr 和 ec 的值是否相等
用法说明
from_chars 用于整数类型的用法说明
-
允许所有内置整数类型,但删除了 bool 类型
-
这些函数已经过测试,支持
__int128
和unsigned __int128
-
当使用
-std=c++14
或更高版本编译时,用于整数类型的 from_chars 是 constexpr-
一个已知的例外是 GCC 5,它不支持
const char*
的 constexpr 比较。
-
-
有效字符串必须仅包含数字字符。 前导空格不会被忽略,并将返回
std::errc::invalid_argument
。
from_chars 用于浮点类型的用法说明
-
在
std::errc::result_out_of_range
时,对于小值(例如 1.0e-99999),我们返回 ±0,对于大值(例如 1.0e+99999),我们返回 ±HUGE_VAL,以匹配std::strtod
的处理方式。 这与标准有所不同,标准声明我们应该返回未修改的value
参数。-
from_chars
在 LWG 中存在一个未解决的问题:https://cplusplus.github.io/LWG/lwg-active.html#3081。 <charconv> 的标准不像 strtod 那样区分下溢和溢出。 假设您正在编写一个 JSON 库,并且出于性能原因,您用boost::charconv::from_chars
替换了std::strtod
。 Charconv 在某些转换时返回 std::errc::result_out_of_range。 然后您必须再次自行解析字符串,以找出获得std::errc::result_out_of_range
的四个可能原因中的哪一个。 Charconv 可以通过在整个代码库中使用boost::charconv::from_chars_erange
而不是boost::charconv::from_chars
来为您提供该信息。 通过实现与已建立的 strtod 行为相匹配的 LWG 问题解决方案,我认为我们提供了正确的行为,而无需等待委员会的决定。
-
-
这些函数已经过测试,支持所有内置浮点类型以及 C++23 的
<stdfloat>
中的类型-
long double 可以是 64 位、80 位或 128 位,但必须符合 IEEE 754 标准。 不符合标准因此不受支持的格式的一个示例是
__ibm128
。 -
使用
__float128
或std::float128_t
需要使用-std=gnu++xx
进行编译并链接 GCC 的libquadmath
。 使用 CMake 构建时会自动完成此操作。
-
示例
基本用法
整数
const char* buffer = "42";
int v = 0;
from_chars_result r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(v == 42);
std::string str_buffer (buffer);
boost::core::string_view sv(str_buffer);
int v2;
auto r2 = boost::charconv::from_chars(sv, v2);
assert(r);
assert(v2 == v);
浮点
const char* buffer = "1.2345"
double v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(v == 1.2345);
std::string str_buffer(buffer);
double v2;
auto r2 = boost::charconv::from_chars(buffer, v2);
assert(r2);
assert(v == v2);
十六进制
整数
const char* buffer = "2a";
unsigned v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v, 16);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(v == 42);
浮点
const char* buffer = "1.3a2bp-10";
double v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v, boost::charconv::chars_format::hex);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(v == 8.0427e-18);
std::errc::invalid_argument
以下代码无效,因为正在将负值解析为无符号整数。
const char* buffer = "-123";
unsigned v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc::invalid_argument);
assert(!r); // Same as above but less verbose. Added in C++26.
以下代码无效,因为定点格式的浮点值不能有指数。
const char* buffer = "-1.573e-3";
double v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v, boost::charconv::chars_format::fixed);
assert(r.ec == std::errc::invalid_argument);
assert(!r); // Same as above but less verbose. Added in C++26.
注意:在发生 std::errc::invalid_argument
事件时,from_chars
不会修改 v
std::errc::result_out_of_range
const char* buffer = "1234";
unsigned char v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc::result_out_of_range);
assert(!r); // Same as above but less verbose. Added in C++26.
assert(v == 0)
注意:在发生 std::errc::result_out_of_range
事件时,from_chars
不会修改 v
to_chars
to_chars 概述
to_chars
是一组函数,尝试将 value
转换为由 [first, last)
指定的字符缓冲区。 to_chars
的结果是 to_chars_result
,成功时返回 ptr
等于写入字符的末尾之后的位置,并且 ec == std::errc()
,失败时返回 std::errc::value_too_large
和 ptr == last
。 to_chars
不会对返回的字符进行 null 终止。
定义
namespace boost { namespace charconv {
struct to_chars_result
{
char* ptr;
std::errc ec;
friend constexpr bool operator==(const to_chars_result& lhs, const to_chars_result& rhs) noexcept; = default;
constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
};
template <typename Integral>
BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars(char* first, char* last, Integral value, int base = 10) noexcept;
template <typename Integral>
BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars<bool>(char* first, char* last, Integral value, int base) noexcept = delete;
template <typename Real>
to_chars_result to_chars(char* first, char* last, Real value, chars_format fmt = chars_format::general, int precision) noexcept;
}} // Namespace boost::charconv
to_chars 参数
-
first, last
- 指向字符缓冲区的开头和结尾的指针 -
value
- 要解析到缓冲区中的值 -
base
(仅限整数)- 要使用的整数基数。 必须介于 2 和 36 之间(包含 2 和 36) -
fmt
(仅限浮点数)- 要使用的浮点格式。 有关描述,请参阅 chars_format 概述。 -
precision
(仅限浮点数)- 所需的小数位数
to_chars_result
-
ptr
- 从to_chars
返回时,成功时指向写入字符的末尾之后的位置,失败时指向last
-
ec
- 错误代码。to_chars
返回的值为
返回值 |
描述 |
|
成功解析 |
|
1) 溢出 2) 下溢 |
-
operator==
- 比较 ptr 和 ec 的值是否相等
用法说明
to_chars 用于整数类型的用法说明
-
允许所有内置整数类型,但删除了 bool 类型
-
当满足以下条件时,用于整数类型的 from_chars 是 constexpr(定义了 BOOST_CHARCONV_CONSTEXPR)
-
使用
-std=c++14
或更高版本编译 -
使用具有
__builtin_ is_constant_evaluated
的编译器
-
-
这些函数已经过测试,支持
__int128
和unsigned __int128
to_chars 用于浮点类型的用法说明
-
处理不同的
NaN
值时,将返回以下内容-
qNaN
返回 "nan" -
-qNaN
返回 "-nan(ind)" -
sNaN
返回 "nan(snan)" -
-sNaN
返回 "-nan(snan)"
-
-
这些函数已经过测试,支持所有内置浮点类型以及 C++23 的
<stdfloat>
中的类型-
Long double 可以是 64 位、80 位或 128 位,但必须符合 IEEE 754 标准。 不符合标准因此不受支持的格式的一个示例是
ibm128
。 -
使用
__float128
或std::float128_t
需要使用-std=gnu++xx
进行编译并链接 GCC 的libquadmath
。 使用 CMake 构建时会自动完成此操作。
-
示例
基本用法
整数
char buffer[64] {};
int v = 42;
to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
assert(r.ec == std::errc());
assert(!strcmp(buffer, "42")); // strcmp returns 0 on match
浮点
char buffer[64] {};
double v = 1e300;
to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "1e+300"));
十六进制
整数
char buffer[64] {};
int v = 42;
to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v, 16);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "2a")); // strcmp returns 0 on match
浮点
char buffer_u[64] {};
double u = -1.08260383390082950e+20;
char buffer_v[64] {};
double v = -1.08260383390082946e+20;
to_chars(buffer_u, buffer_u + sizeof(buffer_u) - 1, u, chars_format::hex);
to_chars(buffer_v, buffer_v + sizeof(buffer_v) - 1, v, chars_format::hex);
std::cout << "U: " << buffer_u << "\nV: " << buffer_v << std::endl;
// U: -1.779a8946bb5fap+66
// V: -1.779a8946bb5f9p+66
//
// With hexfloats we can see the ULP distance between U and V is a - 9 == 1.
std::errc::value_too_large
整数
char buffer[3] {};
int v = -1234;
to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v, 16);
assert(r.ec == std::errc::value_too_large);
assert(!r); // Same as above but less verbose. Added in C++26.
浮点
char buffer[3] {};
double v = 1.2345;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
assert(r.ec == std::errc::value_too_large);
assert(!r); // Same as above but less verbose. Added in C++26.
在发生 std::errc::value_too_large
事件时,to_chars_result.ptr 等于 last
chars_format
chars_format 概述
boost::charconv::chars_format
是一个 enum class
,用于定义浮点类型与 from_chars
和 to_chars
的格式。
定义
namespace boost { namespace charconv {
enum class chars_format : unsigned
{
scientific = 1 << 0,
fixed = 1 << 1,
hex = 1 << 2,
general = fixed | scientific
};
}} // Namespace boost::charconv
格式
科学计数法格式
科学计数法格式的形式为 1.3e+03
。 整数部分将在 0 到 9 之间(包含 0 和 9)。 小数部分和指数将始终出现。 指数将始终至少有 2 位数字。
定点格式
定点格式的形式为 2.30
或 3090
。 此格式不会出现指数。 如果 to_chars
的精度超过类型精度(例如 std::numeric_limits<double>::chars10
),则将在有效数字的末尾追加 0。
十六进制格式
十六进制格式的形式为 1.0cp+05
。 整数部分将始终为 0 或 1。 指数将使用 p 而不是 e,因为 e 是有效的十六进制值。 注意:每个二进制浮点数都有唯一的十六进制浮点数表示形式,但并非每个十六进制浮点数都有唯一的二进制浮点数表示形式。 这是因为 IEEE754 binary32 和 binary64 的有效位数不能被 4 整除。
Hexfloat 用例
对于那些不熟悉十六进制浮点数的人来说,它们在特定情况下很有价值
-
精度控制:十六进制浮点数可以提供对浮点值精度的更精细控制。 在十六进制表示法中,每个数字代表四个位(一个十六进制位),允许您通过指定一定数量的十六进制数字来直接操作数字的精度。 当您需要精确控制计算所需的精度级别时,这可能很有用。
-
位级表示:十六进制浮点数提供了浮点数底层位的直接表示。 每个十六进制数字对应于特定的位组,从而更容易可视化和理解浮点值的内部结构。 这对于调试或分析浮点算术运算(例如,计算 ULP 距离)可能很有帮助。
通用
通用格式将是以定点格式或通用格式表示数字的最短形式(例如 1234
而不是 1.234e+03
)。
限制
限制 概述
<boost/charconv/limits.hpp>
的内容旨在帮助用户优化 to_chars
所需的缓冲区大小。
定义
namespace boost { namespace charconv {
template <typename T>
constexpr int limits<T>::max_chars10;
template <typename T>
constexpr int limits<T>::max_chars;
}} // Namespace boost::charconv
max_chars10
需要传递给 to_chars
的缓冲区的最小大小,以保证成功转换 T 类型的所有值,当未传递基数或传递基数 10 时。
max_chars
需要传递给 to_chars
的缓冲区的最小大小,以保证成功转换 T 类型的所有值,对于任何基数值。
示例
以下两个示例是 max_chars10
,用于优化整数类型和浮点类型的 to_chars
的缓冲区大小。
char buffer [boost::charconv::limits<std::int32_t>::max_chars10;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), std::numeric_limits<std::int32_t>::max());
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "2147483647")); // strcmp returns 0 on match
char buffer [boost::charconv::limits<float>::max_chars10;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), std::numeric_limits<float>::max());
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "3.40282347e+38")); // strcmp returns 0 on match
以下示例是用于序列化二进制(base = 2)整数时 max_chars
的用法。
char buffer [boost::charconv::limits<std::uint16_t>::max_chars;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), std::numeric_limits<std::uint16_t>::max(), 2);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "1111111111111111")); // strcmp returns 0 on match
基准测试
本节介绍了一系列性能基准测试,这些测试将此库与标准库进行了比较,以及如何在需要时运行自己的基准测试。
这些值是相对于 std::printf
和 std::strtoX
的性能而言的。 数字越大,性能越高(例如,2.00 表示快两倍,0.50 表示花费的时间是两倍)。 std::printf
和 std::strtoX
始终列在第一位,因为它们将是参考值。
如何运行基准测试
要自己运行基准测试,请导航到 test 文件夹并在运行测试时定义 BOOST_CHARCONV_RUN_BENCHMARKS
。 例如,在 Linux 上使用 b2:../../../b2 cxxstd=20 toolset=gcc-13 define=BOOST_CHARCONV_RUN_BENCHMARKS STL_benchmark linkflags="-lfmt" -a release
。
此外,您还需要以下内容
-
具有完整
<charconv>
支持的编译器-
GCC 11 或更高版本
-
MSVC 19.24 或更高版本
-
结果
x86_64 Linux
表 1-4 中的数据是在 Ubuntu 23.04 上使用 x86_64 架构和带有 libstdc++ 的 GCC 13.1.0 运行的。
浮点
函数 | 相对性能(float / double) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
0.56 / 0.49 |
Boost.spirit.karma |
1.70 / 2.62 |
std::to_chars |
4.01 / 6.03 |
Boost.Charconv.to_chars |
4.46 / 6.20 |
Google double-conversion |
1.26 / 1.91 |
{fmt} |
2.52 / 3.63 |
函数 | 相对性能(float / double) |
---|---|
std::strto(f/d) |
1.00 / 1.00 |
Boost.lexical_cast |
0.33 / 0.42 |
Boost.spirit.qi |
3.17 / 4.65 |
std::from_chars |
3.23 / 5.77 |
Boost.Charconv.from_chars |
3.28 / 5.75 |
Google double-conversion |
1.16 / 1.30 |
整数
函数 | 相对性能(uint32_t / uint64_t) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
1.80 / 1.38 |
Boost.spirit.karma |
2.81 / 1.62 |
std::to_chars |
4.06 / 2.45 |
Boost.Charconv.to_chars |
4.13 / 2.48 |
{fmt} |
2.88 / 2.21 |
函数 | 相对性能(uint32_t / uint64_t) |
---|---|
std::strto(ul,ull) |
1.00 / 1.00 |
Boost.lexical_cast |
0.53 / 0.52 |
Boost.spirit.qi |
2.24 / 1.49 |
std::from_chars |
1.97 / 1.68 |
Boost.Charconv.from_chars |
2.54 / 1.78 |
x86_64 Windows
表 5-8 中的数据是在 Windows 11 上使用 x86_64 架构和 MSVC 14.3 (V17.7.0) 运行的。
浮点
函数 | 相对性能(float / double) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
0.50 / 0.70 |
Boost.spirit.karma |
2.23 / 7.58 |
std::to_chars |
5.58 / 15.77 |
Boost.Charconv.to_chars |
5.62 / 15.26 |
函数 | 相对性能(float / double) |
---|---|
std::strto(f/d) |
1.00 / 1.00 |
Boost.lexical_cast |
0.14 / 0.20 |
Boost.spirit.qi |
2.03 / 4.58 |
std::from_chars |
1.01 / 1.23 |
Boost.Charconv.from_chars |
2.06 / 5.21 |
整数
函数 | 相对性能(uint32_t / uint64_t) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
0.68 / 0.68 |
Boost.spirit.karma |
2.75 / 1.67 |
std::to_chars |
2.75 / 2.10 |
Boost.Charconv.to_chars |
2.75 / 2.06 |
函数 | 相对性能(uint32_t / uint64_t) |
---|---|
std::strto(ul,ull) |
1.00 / 1.00 |
Boost.lexical_cast |
0.46 / 0.39 |
Boost.spirit.qi |
1.94 / 1.63 |
std::from_chars |
2.43 / 2.18 |
Boost.Charconv.from_chars |
2.68 / 2.27 |
ARM MacOS
表 9-12 中的数据是在 MacOS Ventura 13.5.2 上使用 M1 Pro 架构和带有 libstdc++ 的 Homebrew GCC 13.2.0 运行的。
浮点
函数 | 相对性能(float / double) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
0.58 / 0.16 |
Boost.spirit.karma |
1.39 / 1.22 |
std::to_chars |
6.78 / 6.47 |
Boost.Charconv.to_chars |
7.25 / 6.86 |
Google double-conversion |
2.26 / 2.16 |
{fmt} |
3.78 / 3.38 |
函数 | 相对性能(float / double) |
---|---|
std::strto(f/d) |
1.00 / 1.00 |
Boost.lexical_cast |
0.06 / 0.06 |
Boost.spirit.qi |
1.12 / 1.06 |
std::from_chars |
1.32 / 1.65 |
Boost.Charconv.from_chars |
1.28 / 1.63 |
Google double-conversion |
0.45 / 0.32 |
整数
函数 | 相对性能(uint32_t / uint64_t) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
2.08 / 1.75 |
Boost.spirit.karma |
4.17 / 2.06 |
std::to_chars |
6.25 / 4.12 |
Boost.Charconv.to_chars |
6.25 / 4.12 |
{fmt} |
5.29 / 3.47 |
函数 | 相对性能(uint32_t / uint64_t) |
---|---|
std::strto(ul,ull) |
1.00 / 1.00 |
Boost.lexical_cast |
0.56 / 0.54 |
Boost.spirit.qi |
1.39 / 1.33 |
std::from_chars |
1.92 / 1.65 |
Boost.Charconv.from_chars |
2.27 / 1.65 |
来源
以下论文和博客文章构成了库中使用的算法的基础
-
J.R. Parker 通用字符到整数转换方法,Software: Practice and Experience 15 (8), 1985.
-
Junekey Jeon, 更快的整数格式化 - James Anhalt (jeaiii) 的算法
-
Junekey Jeon, Dragonbox:一种新的浮点二进制到十进制转换算法
-
Junekey Jeon, 浮点数的固定精度格式化
-
William D. Clinger, 如何准确读取浮点数, 1990
-
Daniel Lemire, 每秒千兆字节的数字解析,Software: Practice and Experience 51 (8), 2021.
-
Noble Mushtak, Daniel Lemire, 没有回退的快速数字解析,Software: Practice and Experience (即将发表)
-
Ulf Adams, Ryū revisited: printf 浮点转换,Proceedings of the ACM on Programming Languages Volume 3, 2019
致谢
特别感谢以下人员(非详尽列表)
-
Peter Dimov,感谢他在整个开发过程中提供技术指导并为库做出贡献。
-
Junekey Jeon,感谢他开发并解答了我关于他的整数格式化、Dragonbox 和 Floff 的问题。
-
Chris Kormanyos,感谢他担任库审查经理。
-
Stephan T. Lavavej,感谢他为基准测试奠定了基础。
-
感谢所有审查库并提供反馈以使其变得更好的人。
版权和许可证
本文档的版权归 2022-2023 Peter Dimov 和 Matt Borland 所有,并根据 Boost 软件许可证 1.0 版 分发。