Ovid has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to verify some regex optimizations, so I decided to benchmark my code.
#!/usr/bin/perl -w use strict; my $myvar = 'Tom said "hi," and Sally replied "get lost, Ovid is more +my style."'; use Benchmark; timethese(100000, { Greedy => '$myvar =~ /"(.*)"/', Lazy => '$myvar =~ /"(.*?)"/', Negated => '$myvar =~ /"[^"]*"/' });
Unfortunately, the above code keeps giving me the following error:
Use of uninitialized value at (eval 2) line 1.
I've tried swapping out the single quotes, the double quotes, and even tried running the debugger on it (yeah, I know that must do wonders for timing your code). I've also read up on a fair amount of documentation for this, all to no avail! Help

Thanks in advance for any advice!

Cheers,
Ovid

Replies are listed 'Best First'.
RE: Help using Benchmark.pm
by autark (Friar) on Jul 12, 2000 at 23:02 UTC
    Hi,

    Your problem can be solved by making $myvar a global, either by using:

    use vars qw|$myvar|; $myvar = "...";
    or if you use perl 5.6:
    our $myvar = "...";
    It can also be solved by letting the keys in that hash point to functions:
    timethese(100000, { Greedy => sub { $myvar =~ /"(.*)"/ }, Lazy => sub { $myvar =~ /"(.*?)"/ }, Negated => sub { $myvar =~ /"[^"]*"/ } });
    If the value of one of the keys is not a reference to a function, Benchmark is forced to eval your code - and when you eval a string all the variables referenced within it will be looked up in the stash (where all the symbols live) - they are treated as globals you could say. That's why it works when you make $myvar a non-lexical variable.

    Autark.

Re: Help using Benchmark.pm
by btrott (Parson) on Jul 12, 2000 at 22:59 UTC
    use vars qw/$myvar/;
    No my.

    Don't declare it as lexical, because it won't be in scope when you're actually running the benchmarked code. Or rather when Benchmark is running your code.

RE: Help using Benchmark.pm
by Adam (Vicar) on Jul 12, 2000 at 22:53 UTC
    You need to give $myvar a value in each snippet.
    Greedy => '$myvar =~ /"(.*)"/',
    becomes
    Greedy => '$myvar = "Some String"; $myvar =~ /"(.*)"/',
    For more advice see the node Benchmarking Your Code.

    Update: I see that I located the problem (scoping), but not the cause.(the my)

RE: Help using Benchmark.pm
by Ovid (Cardinal) on Jul 12, 2000 at 23:14 UTC
    Thanks for the help everyone! It's now running just fine :)