Boost C++ 库

...世界上最受推崇和设计最精湛的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

概述

描述

Boost.Charconv 在字符缓冲区和数字之间进行转换。它是一个小型库,包含两个重载函数来完成繁重的工作,以及几个支持性的枚举、结构体、模板和常量,特别关注性能和跨受支持开发环境的一致性。

我为什么要对这个库感兴趣? Charconv 是独立于区域设置的,非分配内存1,不抛出异常,并且仅需要最低限度的 C++ 11。它提供的功能类似于 std::printfstd::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 ActionsDrone 上进行了测试。

入门指南

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 文档

__float128std::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

from_chars

from_chars 概述

from_chars 是一组函数,用于解析来自 [first, last) 的字符串,尝试根据指定的 chars_format(如果适用)将字符串转换为 value。 数字的解析是独立于区域设置的(例如,等效于“C”区域设置)。 from_chars 的结果是 from_chars_result,成功时返回 ptr == lastec == std::errc(),失败时返回 ptr 等于最后一个解析的有效字符或下溢/溢出时的 last,以及 ec == std::errc::invalid_argumentstd::errc::result_out_of_rangefrom_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 返回的值为

返回值

描述

std::errc()

成功解析

std::errc::invalid_argument

1) 将负数解析为无符号类型

2) 前导 + 符号

3) 前导空格

4) 不兼容的格式(例如,chars_format::fixed 上的指数,或不是 chars_format::hex 的值上的 p 作为指数)请参阅 chars_format 概述

std::errc::result_out_of_range

1) 溢出

2) 下溢

  • operator== - 比较 ptr 和 ec 的值是否相等

用法说明

from_chars 用于整数类型的用法说明

  • 允许所有内置整数类型,但删除了 bool 类型

  • 这些函数已经过测试,支持 __int128unsigned __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

    • 使用 __float128std::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_largeptr == lastto_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 返回的值为

返回值

描述

std::errc()

成功解析

std::errc::value_too_large

1) 溢出

2) 下溢

  • operator== - 比较 ptr 和 ec 的值是否相等

用法说明

to_chars 用于整数类型的用法说明

  • 允许所有内置整数类型,但删除了 bool 类型

  • 当满足以下条件时,用于整数类型的 from_chars 是 constexpr(定义了 BOOST_CHARCONV_CONSTEXPR)

    • 使用 -std=c++14 或更高版本编译

    • 使用具有 __builtin_ is_constant_evaluated 的编译器

  • 这些函数已经过测试,支持 __int128unsigned __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

    • 使用 __float128std::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_charsto_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.303090。 此格式不会出现指数。 如果 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::printfstd::strtoX 的性能而言的。 数字越大,性能越高(例如,2.00 表示快两倍,0.50 表示花费的时间是两倍)。 std::printfstd::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

此外,您还需要以下内容

结果

x86_64 Linux

表 1-4 中的数据是在 Ubuntu 23.04 上使用 x86_64 架构和带有 libstdc++ 的 GCC 13.1.0 运行的。

浮点
表 1. to_chars 浮点数,采用最短表示形式
函数 相对性能(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

表 2. from_chars 浮点数,采用科学计数法格式
函数 相对性能(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

整数
表 3. to_chars 基数为 10 的整数
函数 相对性能(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

表 4. from_chars 基数为 10 的整数
函数 相对性能(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) 运行的。

浮点
表 5. to_chars 浮点数,采用最短表示形式
函数 相对性能(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

表 6. from_chars 浮点数,采用科学计数法格式
函数 相对性能(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

整数
表 7. to_chars 基数为 10 的整数
函数 相对性能(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

表 8. from_chars 基数为 10 的整数
函数 相对性能(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 运行的。

浮点
表 9. to_chars 浮点数,采用最短表示形式
函数 相对性能(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

表 10. from_chars 浮点数,采用科学计数法格式
函数 相对性能(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

整数
表 11. to_chars 基数为 10 的整数
函数 相对性能(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

表 12. from_chars 基数为 10 的整数
函数 相对性能(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

来源

以下论文和博客文章构成了库中使用的算法的基础

致谢

特别感谢以下人员(非详尽列表)

  • Peter Dimov,感谢他在整个开发过程中提供技术指导并为库做出贡献。

  • Junekey Jeon,感谢他开发并解答了我关于他的整数格式化、Dragonbox 和 Floff 的问题。

  • Chris Kormanyos,感谢他担任库审查经理。

  • Stephan T. Lavavej,感谢他为基准测试奠定了基础。

  • 感谢所有审查库并提供反馈以使其变得更好的人。

本文档的版权归 2022-2023 Peter Dimov 和 Matt Borland 所有,并根据 Boost 软件许可证 1.0 版 分发。