c++11標準庫的regex比boost庫的regex之間的性能差距接近5倍,這是爲何?stackflow上也找到一篇post《c++11 regex slower than python》,你們在7年前就有討論了,可是沒有一個答案。裏面有人給出boost快5倍的例子。python
今天就此作一個小小的profile 進行分析對比。c++
環境:devtoolset-7 on atlarch centos 7,git
編譯連接:O2優化,boost169 on dnf。github
測試內容:100次 regex_search,由於不是benchmark,因此少許100次。測試代碼放在結尾。centos
量化單位:self 欄指令週期,call欄次數。網絡
如今開始分析profile,每張圖上面是boost::regex-profile,下面是std::regex-profile。dom
上圖,ld.so能夠看做一個進程的基本開銷,兩者是至關的,因此除去。post
測試程序名稱是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。