in reply to Compiling Search/Replace Regexs

You are mistaken in when things are compiled. Please see /o is dead, long live qr//! for an in depth look at when regular expressions are compiled. That description completely ignores the right hand side (RHS) of a search-replace operation for good reason. It is already compiled at during the normal BEGIN-time compile time. A static, non-interpoloating RHS is a constant for perl. That's the fastest. A static interpolating RHS (use of $1 will trigger this) is a plain concatenation. This is also as optimal as it can get. Pushing the concatentation into a subroutine means you still do the same concatenation but you also incur the cost of a function call. Obviously, opting to do non-productive work is going to slow things down.

Please trust that your RHS is already compiled appropriately when you write things like s/.../RHS $1/. It is not recompiled whenever the left hand side (LHS) changes.

The document I linked to informs you that the LHS is recompiled anytime the s/// or m// was not given a complete, compiled regexp and the stringification of the regexp is not identical to the last time the regexp was compiled. In practice, this means that if you use the same pattern more than once in a row, it is compiled only once. Depending on whether you are passing in a string or a compiled regexp object, you may incur the cost of doing a string equality check. This is the same code that eq uses.

Please note that it is entirely innappropriate to consider the use of qr// for your RHS. This should be obvious to you by not but if not, note that now. You only ever use the result of a qr// on the LHS.

If you have multiple regexes you wish to cache and you aren't going to name each one individually. Here, you store a compiled regex in a hash keyed to whatever the text of the regex is. Your replacement uses the text as a lookup to get the compiled version.

# $cache{$regex} ||= qr/$regex/; $string =~ s/$cache{$regex}/XXX$1/

If you have a single regex you'd like to name and cache, this is even nicer. You can avoid a hash lookup.

$something_regex = qr/$regex/; $string =~ s/$something_regex/XXX$1/