我對這裏發生的事情感到困惑。我所看到的大多數基準測試都表明Boost已經接近Perl,甚至在性能方面更勝一籌。然而,在我的腳本中,我的Perl實現速度是5-6倍。Perl正則表達式比C++ Boost實現運行速度快
我在test_script.cpp中打開文件& test_script.pl並逐行閱讀,填充數組。然後,我將這些字符串對照線性定義中的正則表達式列表運行,直到它們匹配,在這種情況下沒有任何反應(爲了測試目的而刪除了I/O),然後比較下一個字符串,直到我們比較了所有字符串。
Test_script.pl:
#make incomingList, which contains all incoming strings
my $start = Time::HiRes::gettimeofday();
foreach (@incomingList) {
my $inString = $_;
&find_pattern($inString);
}
my $end = Time::HiRes::gettimeofday();
printf("%.6f\n", $end - $start);
Find_pattern方法:
sub find_pattern {
my $URLString = $_[0];
#1 rewrite
if($URLString =~ m/^\/stuff\/brands-([^\/]*)\/(.*)?$/) {
}
#2 rewrite
elsif($URLString =~ m/^\/coupons(\/.*)?$/){
}
#3 rewrite
elsif($URLString =~ m/^\/han\/(.+)$/){
}
# ...continues on, there are 100 patterns.
}
Test_script.cpp: 主要方法:
populateArray();
//make stringArr, which contains all incoming strings
struct timeval time;
gettimeofday(&time, NULL);
double t1=time.tv_sec+(time.tv_usec/1000000.0);
for(int j =0; j < 10000; j++){
getRule(stringArr[j]);
}
gettimeofday(&time, NULL);
double t2=time.tv_sec+(time.tv_usec/1000000.0);
printf("%.6lf seconds elapsed\n", t2-t1);
填入陣列的方法:
static void populateArray(){
regexArray[1] = boost::regex ("\\/stuff\\/brands-([^\\/]*)\\/(.*)?");
regexArray[2] = boost::regex ("\\/coupons(\\/.*)?");
regexArray[3] = boost::regex ("\\/han\\/(.+)");
//continues on, 100 definitions.
}
getRule方法:
static void getRule(string inQuery){
for(int i =1; i < 100; i++){
if(boost::regex_match(inQuery, regexArray[i])){
break;
}
}
我明白,這似乎有些奇怪,我做的,如果在Perl其他檢查線性表,但那是因爲我有獨立之後重新格式化每個規則。無論如何,除非我誤解了某些內容,否則這兩個腳本非常相似 - 他們會查看這個正則表達式列表,直到找到匹配,然後繼續處理其他傳入的字符串。
那麼爲什麼這些結果如此不同呢? 對於100條規則(同樣用於兩個腳本)& 10,000個輸入, .cpp的平均值約爲0.155秒,.pl的平均值約爲0.028秒。 編輯:通過編譯優化,C++腳本的運行時間大約爲0.091秒,仍然較慢。
任何洞察力是讚賞。
您是否使用優化進行編譯?你在調試中運行嗎? –
請注意,perl版本中的第二個模式在末尾沒有錨定。其他的事情,我不使用提升,但如果我記得默認模式使用ECMA正則表達式引擎,您是否嘗試使用PCRE正則表達式引擎*(具有更多優化功能)*? –
我使用./test_script -lrt -lboost_regex編譯C++,然後運行該可執行文件。謝謝,修正了這種模式。 – Yayahii