perl预编译的正则表达式问题

时间:2009-12-04 19:58:33

标签: regex perl

我是否真的从以下方面获得了任何好处(而不是仅在两个if语句中使用实际的正则表达式代替$ {pcr})? (实际数据集中有更多行,但仅使用DATA。

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>

2 个答案:

答案 0 :(得分: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 :(得分:1)

使用perl的'times'来获取以下循环之前和之后的cpu时间,这表明由于某种原因,预编译的正则表达式版本实际上比内联正则表达式慢约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>';

找到delta和平均值后的cpu时间为:

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

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

由于个人原因,我没有使用perl的Benchmark.pm。我已经看到它给出了明显错误的数字,虽然它们很小,但如果你有不可信任的数字,基准测试是毫无意义的。我可以信任的这些数字,虽然我可能需要重新评估基准测试。