in reply to Re^3: speeding up a regex
in thread speeding up a regex

In modern Perls -- I'm not sure which versions qualify here, maybe 5.6+ -- Perl will check whether the contents of the variable has changed. If the content of the variable has not changed, the regexp is not recompiled.
...
foreach my $word (@words) { if (/\Q$word/) { # BAD!! $word always changes.
Hi ikegami,

Thanks for the very informative post! A quick question: I thought that in a loop like the one above, the iterator variable ($word) was temporarily aliased to each value of the array. So I would expect that as long as the array's contents didn't change, perl would know not to recompile the RE, and so both of your above examples would be the same speed.

But a quick Benchmark agrees with you: putting the RE in the outer loop is about twice as fast as in the inner loop.

Any hints as to what's wrong with my understanding of variable aliasing or RE caching?

Thanks!

Replies are listed 'Best First'.
Re^5: speeding up a regex
by ikegami (Patriarch) on Jan 03, 2006 at 21:07 UTC

    What matters is the value of $word, because we're using the value of $word to compile the regexp. While the value of the variable to which $word is/was aliased doesn't change, the value of $word itself does change.

    In the first pass, $word is "foo". The regexp was thus compiled with to /foo/. In the second pass, $word is "bar". We obviously need to recompile the regexp because we want /bar/ and it's currently /foo/. Whether $words[0] and $words[1] changed or not is completely irrelevant.

    You might be thinking that the compiled regexp is stored with the variable used in the regexp. It's not. That wouldn't work when no variables or multiple variables are used to create the regexps. Instead, the uncompiled regexp or the values of the variables used to compile the regexp -- I don't know which -- is stored along with the compiled regexp in the code.