itoa-benchmark, C++ 整数到字符串转换基准

分享于 

6分钟阅读

GitHub

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

    Copyright(c) 2014 -2016 ( miloyip@gmail.com )

    简介

    这个基准评估从 32 -bit/64位 整数转换为十进制字符串的性能。 函数Prototype包括:

    voidu32toa(uint32_t value, char* buffer);voidi32toa(int32_t value, char* buffer);voidu64toa(uint64_t value, char* buffer);voidi64toa(int64_t value, char* buffer);

    注意,itoa() 是 ,不是C 和中的标准函数,而是由一些编译器提供。

    过程

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

    然后,执行两种基准测试:

    连续: 以相同位数的十进制数转换连续值。

    对于 u32toa(),测试的值是 { 1,2. ,9 }, {10, 11. ,99 },。{ 4000000000,4000000001. 4294967296 }, 换句话说,1至 10十进制数字组。

    对于签名版本,请使用备用标志,比如 { 1,-2,3,-4."。 9 }.

    对于 64位 整数,有 1到 20个十进制数字组。

    随机: 转换第一个事例的打乱顺序。

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

    构建和运行

    结果

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

    函数时间( ns ) 加速
    sprintf194.2251.00x
    vc61.5223.16x
    天真26.7437.26x
    计数数20.5529.45x
    lut17.81010.91x
    countlut9.92619.57x
    branchlut8.43023.04x
    sse27.61425.51x
    2.23087.09x

    corei7920@2.67_win64_vc2013_u32toa_sequential_time

    corei7920@2.67_win64_vc2013_u32toa_sequential_timedigit

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

    由于 C++ 标准库实现( ostringstreamostrstreamto_string ) 很慢,默认情况下它们是关闭的。 用户可以通过定义 RUN_CPPITOA 宏来启用它们。

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

    插件实现

    ostringstreamC++ 标准库中的std::ostringstream
    ostrstreamC++ 标准库中的std::ostrstream
    to_stringC++11标准库中的std::to_string()
    sprintfC 标准库中的sprintf()
    vcC++,_i64toa()_ui64toa()的可视化 _itoa()
    天真计算每个数字的10/模,将数字存储在临时 array 中,并以相反顺序复制到缓冲区。
    未命名计算每个数字 10的除法/模,直接存储在缓冲区中
    计数数先使用 [1] 技术计算十进制数的计数。
    lut使用数字对的查找表( LUT ) 进行 100的除法/模运算。 在 [2 ] 中提到
    countlut组合计数和 lut。
    branchlut使用分支divide-and-conquer值范围,使计算更并行。
    sse2基于branchlut格式,使用 SSE2 SIMD指令并行转换 8位数字。 ( 实验表明它对于等于或者大于 9位数字的值很有用)
    什么也不做。

    常见问题解答

    如何添加实现?

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

    欢迎新实现的拉请求。

    为什么不将整数转换为 std::string

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

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

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

    引用

    [1],位Twiddling黑客攻击,。

    [2] Alexandrescu,三个针对 C++的优化提示,2012.

    相关基准和讨论


    相关文章