• std::regex与boost::regex的性能差5倍,有profile有真相。


    c++11标准库的regex比boost库的regex之间的性能差距接近5倍,这是为什么?stackflow上也找到一篇post《c++11 regex slower than python》,大家在7年前就有讨论了,但是没有一个答案。里面有人给出boost快5倍的例子。

    今天就此做一个小小的profile 进行分析对比。

    环境:devtoolset-7 on atlarch centos 7,

    编译链接:O2优化,boost169 on dnf。

    测试内容:100次 regex_search,因为不是benchmark,所以少量100次。测试代码放在结尾。

    量化单位:self 栏指令周期,call栏次数。

    现在开始分析profile,每张图上面是boost::regex-profile,下面是std::regex-profile。

    上图,ld.so可以看作一个进程的基本开销,二者是相当的,所以除去。

    测试程序名称是zbuffer,即@MAIN主映像,regex代码内联在这个模块。

    主要模块的profile对比

    模块名  boost  std
     @MAIN  329608  3966488
     libstdc++  577719  1527035
     libc  137741  913459
     libboost_regex  117581  57632
         
         

    主要差距存在前俩, boost约90w,std约450w,接近5倍。

    可以直观看出,boost库在@MAIN内联的代码,加上库的执行代码,性能消耗十分少,不到50w,比std::regex程序在libc上消耗的还少的多。std::regex究竟做什么了。

    第二张图是主模块的profile对比,std::regex主要消耗在前8项,主要有_Execute,new,delete。

    std::regex的_Execute占了120W,new+delete占了180W。

    抛开new+delete操作的巨大损耗,std::regex的_Execute的消耗依旧比boost::regex全部消耗高出1倍。

    第三张图是libstdc++的profile对比,

    boost基本没多少new的操作,std::regex却又大量动态类型操作,损耗50w。这损耗量,boost::regex已经足够完成工作了。

    第四张图是libboost_regex的profile。

    因为,std::regex测试程序也链接了libboost_regex.so,正好可以观察std::regex又在什么破事情是损耗。boost在这个模块上的消耗时实实在在的,10w+。std::regex测试程序在libstdc++库的std::string::_S_construct被libboost_regex库接替,反过来看,std::regex的std::string多了3400+次的操作。

    最后一张图是libc的profile

    boost::regex与std::regex的profile对比完结。

    测试代码来自网络

        int veces = 100;
        int count = 0;
    
        zlab_allocator<>::inst();
    
        using namespace std;
        regex expres ("([^-]*)-([^-]*)-(\d\d\d:\d\d)---(.*)\n",
                         regex_constants::ECMAScript);
    
        std::string text ("some-random-text-453:10--- etc etc blah
    ");
        smatch macha;
        auto start = std::chrono::system_clock::now();
    
        for (int ii = 0;  ii < veces; ii ++)
            count += regex_search (text, macha, expres);
    
        auto milli = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count();     
        std::cout << count << "/" << veces << " matches " << milli << " ms --> " << (milli / (float) veces) << " ms per regex_search" << std::endl;
        

    profile文件放在我的github.com/bbqz007

  • 相关阅读:
    阶段一Python核心编程:流程控制之条件语句004
    阶段一Python核心编程:输入、转换数据类型、运算符003
    Linux在线测网速
    SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808)
    SSL/TLS 服务器瞬时 Diffie-Hellman 公共密钥过弱
    oracle归档的开启与关闭
    tmux的使用
    linux下获取占用CPU资源最多的10个进程
    oracle11g安装
    redis学习2
  • 原文地址:https://www.cnblogs.com/bbqzsl/p/13714008.html
Copyright © 2020-2023  润新知