dtoa-benchmark, C++ double至字符串转换基准

分享于 

6分钟阅读

GitHub

  繁體 雙語
C++ double-to-string conversion benchmark
  • 源代码名称:dtoa-benchmark
  • 源代码网址:http://www.github.com/miloyip/dtoa-benchmark
  • dtoa-benchmark源代码文档
  • dtoa-benchmark源代码下载
  • Git URL:
    git://www.github.com/miloyip/dtoa-benchmark.git
    Git Clone代码到本地:
    git clone http://www.github.com/miloyip/dtoa-benchmark
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/miloyip/dtoa-benchmark
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    dtoa基准测试

    Copyright(c) 2014 Milo ( miloyip@gmail.com )

    简介

    这个基准评估了双精度 IEEE-754 浮点( double ) 到ASCII字符串的转换性能。 函数Prototype是:

    voiddtoa(double value, char* buffer);

    通过正确的strtod()。换句话说,往返转换,字符字符串结果必须以的正确的implementation convertible转换为 original。

    请注意,dtoa() 是一个标准函数,不是C 和 C++ 中的标准函数。

    过程

    首先,程序验证了实现的正确性。

    然后,对基准进行了一个例子:

    • RandomDigit: 生成 1000个随机 double 值,过滤出 +/-infnan。 然后将它们转换为有限精度(。significand中的1至 17小数位数)。 finally 将这些数字转换为ASCII格式。

    每个数字组运行 100次。 测试 10个试验的最短时间持续时间。

    构建和运行

    • 获取 premake4
    • 将premake4可执行文件复制到 dtoa-benchmark/build 文件夹( 或者系统路径)。
    • dtoa-benchmark/build 中运行 premake.bat 或者 premake.sh
    • 在 Windows 上,在 dtoa-benchmark/build/vs2008/ 或者 /vs2010/ 上构建解决方案。
    • 在其他平台上,在 dtoa-benchmark/build/gmake/ 处运行 GNU make config=release32 ( 或者 release64 )
    • 在成功时,运行 dtoa 可以执行文件在 dtoa-benchmark/
    • CSV格式的结果将被写入 dtoa-benchmark/result
    • dtoa-benchmark/result 中运行 GNU make 以在HTML中生成结果。

    结果

    以下是在PC上测量的sequential 结果( 核心处理器 920 @2.67Ghz),,u32toa() 由 Visual C++ 2013编译,并运行在 Windows 64位 上)。 加速是基于 sprintf()的。

    ostringstream2,778.7480.45x
    ostrstream2,628.3650.48x
    gay1,646.3100.76x
    sprintf1,256.3761.00x
    fpconv273.8224.59x
    grisu2220.2515.70x
    doubleconv201.6456.23x
    麦洛138.0219.10x
    2.146585.58x

    corei7920@2.67_win64_vc2013_randomdigit_time

    corei7920@2.67_win64_vc2013_randomdigit_timedigit

    请注意,null 实现没有执行任何操作。 它度量循环和函数调用的开销。

    各种配置的一些结果位于 dtoa-benchmark/result。 可以通过 Google图表插件提供的交互式提供在线访问:

    插件实现

    ostringstreamC++ 标准库中的std::ostringstream,带 setprecision(17)
    ostrstreamC++ 标准库中的std::ostrstream,带 setprecision(17)
    sprintfC 标准库中 "%.17g" 格式的sprintf()
    stb_sprintf使用 "%.17g" 格式快速替换 sprintf。
    gay dtoa() 实现的。
    grisu2loitsch C 实现 [1]的Florian Grisu2.
    doubleconvEcmaScriptConverter().ToShortest() 引擎中提取的C++ 实现( ( 基于 Grisu3,当Grisu3未能产生最短的实现时,回退到较慢的bignum算法) )。
    fpconv夜班 Grisu2实现。
    麦洛miloyip C++ 头的Grisu2实现。
    什么也不做。

    注释:

    tostring() 未被测试,因为它不满足往返要求。

    由于Grisu2可以生成更好的人体读数和> 99.结果的9%是最短的。 Grisu3需要另一个 dtoa() 实现来满足最短要求。

    常见问题解答

    如何添加实现?

    你可以克隆现有的实现文件。 然后修改它,运行 premake 将它的添加到项目或者makefile中。 请注意,它将通过宏 REGISTER_TEST(name) 自动 register 到基准。

    欢迎新实现的拉请求。

    为什么不将 double 转换为 std::string

    它可能会引入堆分配,这是一个。 如果需要,用户可以轻松地包装这些低级函数以返回 std::string

    为什么需要快速 dtoa() 功能?

    它们是在文本格式中写入数据时非常常见的操作。 标准的sprintf()std::stringstream的标准方式,常常提供糟糕的性能。 这里基准的作者将在 RapidJSON 中优化 sprintf 实现,因此他创建了这个项目。

    引用

    [1] Loitsch,Florian,"用整数快速准确地打印浮点数。" ACM Sigplan注意 45.6 ( 2010 ): 233 -243。

    相关基准和讨论


    相关文章