2009-12-04 56 views
2

我是否真的從下面的操作中獲得任何好處(而不是將兩個if語句中的實際正則表達式替換爲$ {pcr})? (很多更行是在真實數據集,但只是用數據爲例。perl預編譯的正則表達式問題

my $defs = 0; 
my $tests = 0; 
my $pcr = qr/\s*[\/\\]?\s*/; 
while (<DATA>) 
{ 
    $defs = ($1 ? 0 : 1) if /<(${pcr})definitions/; 
    $tests = ($1 ? 0 : 1) if /<(${pcr})tests/; 
    print "defs: $defs\ntests: $tests\n\n"; 
} 

__DATA__ 
<what> 
</what> 
<definitions> 
<one /> 
</definitions> 
<tests> 
<two /> 
<three /> 
</tests> 
+1

當你自己進行基準測試時會發生什麼? – 2009-12-04 20:01:26

+0

我只是想知道一般真的,因爲我不太瞭解perl中的預編譯正則表達式,在我看來,既然你把預編譯正則表達式放在另一個正則表達式語句中,它無論如何都必須重新編譯。 – user105033 2009-12-04 20:03:29

+0

是的。我想知道如何找出這樣的事情! – 2009-12-04 20:05:20

回答

5

運行鍼對您的原來的例子一些基準,沒有PCR的例子,其中兩個不同的PCR的用於definitionstests另一個例子,這是在循環外定義,我得到五十萬次迭代如下結果我的機器上。

   Rate  no_pcr  orig pcr_before 
no_pcr  130208/s   --  -1%  -5% 
orig  131579/s   1%   --  -4% 
pcr_before 137741/s   6%   5%   -- 

所以它似乎要麼沒有任何好處,或者好處是非常小的

1

在下面的循環前後使用perl的'times'來獲取cpu時間顯示出,由於某種原因,預編譯的regex版本實際上比內聯regex慢33%左右。我做了兩次正則表達式匹配,以接近示例代碼,並防止跨循環運行的任何神祕的perl優化。

for (1..$num_runs) { 
    $test_string =~ $pcr; 
    $test_string =~ $pcr; 
} 

for(1..$num_runs) { 
    $test_string =~ m/\s*[\/\\]?\s*/; 
    $test_string =~ m/\s*[\/\\]?\s*/; 
} 

隨着$num_runs爲10,000,000和$pcr$test_string在下面的:

my $pcr = qr/\s*[\/\\]?\s*/; 
my $test_string = '<what>'; 

找到三角洲和平均後的CPU時間爲:

------------------------------ 
Precompiled regex: 
------------------------------ 
     user : 0.0000040190 
    system : 0.0000000010 

------------------------------ 
Inline regex: 
------------------------------ 
     user : 0.0000030580 
    system : 0.0000000000 

由於個人原因,我沒有使用perl的Benchmark.pm。我已經看到它給出了明顯錯誤的數字,儘管它們很小,但如果你有一些你不能相信的數字,基準測試就毫無意義。這些數字我可以信任,儘管我測試過的測試可能需要重新評估。

+0

嗯,有趣。我知道你不喜歡'Benchmark',但是當我用它來測試你在這裏代替我的原始測試的代碼時,我得到了類似的結果:根據「Benchmark」,非正則表達式版本的速度提高了24%我的機器。 – 2009-12-05 19:51:11

+0

這是non-pcr,不是非正則表達式。哎呀。 :) – 2009-12-05 21:35:09