2009-12-04 23 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