tags:

views:

143

answers:

2

Do I really get any benefit out of doing the following (as opposed to just putting the actual regex in place of the ${pcr} in both if statements)? (alot more lines are in the real data set but just using DATA for example.

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>
+5  A: 

Running some benchmarks against your original example, an example without PCR, and another example where two different PCR's are used for definitions and tests, which are defined outside the loop, I get the following results for half a million iterations on my machine:

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

So it would seem that either there isn't any benefit, or the benefit is very small.

Adam Bellaire
+1  A: 

Using perl's 'times' to get the cpu times before and after the following loops shows me that, for some reason, the precompiled regex version is actually about 33% slower than the inline regex. I did the regex match twice to be close to the example code and to prevent any mysterious perl optimization across loop runs.

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

and

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

With $num_runs being 10,000,000 and $pcr and $test_string being the following:

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

The cpu times after finding the delta and averaging were:

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

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

I did not use perl's Benchmark.pm for personal reasons. I've seen it give obviously wrong numbers and, while they were minimal, benchmarking is pointless if you've got numbers you can't trust. These numbers I can trust, though the tests I benchmarked might need to be reevaluated.

jsoverson
Hmm, interesting. I know you don't like `Benchmark`, but when I use it to test the code you gave here in place of my original tests, I get similar results: The non-regex version is 24% faster according to `Benchmark` on my machine.
Adam Bellaire
That's non-pcr, not non-regex. Oops. :)
Adam Bellaire