profile對比std::regex與boost::regex的效能

bbqz007發表於2020-09-22

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\n");
    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

 

相關文章