技術的な質問:
与えられた正規表現:
my $regEx = qr{whatever$myVar}oxi; # Notice /o for "compile-once"
オンデマンドで強制的に再コンパイルする最も効果的な方法は何ですか? $myVar
(たとえば、値が変更されたことをプログラムロジックから知っている場合) ドロップせず/o
に、Perl の内部スマートに依存して自動再コンパイルしますか?
注: 正規表現は置換で使用され、/o を使用しない再コンパイル ルールに影響を与える可能性があります。
$string2 =~ s/$regEx//;
コンテキストは次のとおりです。
構成ファイルからかなり長い (> 1k の長さ) 文字列を丸呑みすることによって構築された正規表現があります。
そのファイルは 60 分ごとに 1 回再読み取りされます。
ファイルから読み取った文字列が変更された場合 (ファイルのタイムスタンプを変更することで定義
$myVar
) 、.
この正規表現は、mod_perl の下で実行される Perl モジュールで繰り返し頻繁に使用されます。
これは、(文字列の長さが >1-2k であることと相まって) " " 修飾子を使用
/o
して、変数値が変更されたかどうかを繰り返しチェックする Perl のパフォーマンス ヒットを回避するために、正規表現でコンパイル ワンスを強制する必要があることを意味します (このヒューリスティックはperlop qr//
、正規表現は、s///
上記のように の一部として使用され、それ自体では一致として使用されません)。つまり、変数を 1 時間で再スラープした後に変数が変更されたことがわかっている場合は、
/o
修飾子に関係なく、正規表現を強制的に再コンパイルする必要があります。
更新:これが必要な理由の図です/o
-それがないと、正規表現はループの繰り返しごとに再コンパイルされます(したがって、必然的にチェックされます)。それはそうではありません:
$ perl -e '{for (my $i=0; $i<3; $i++) {
my $re = qr{$i}oix; $s="123"; $s =~ s/$re//;
print "i=$i; s=$s\n"; }}'
i=0; s=123
i=1; s=123
i=2; s=123
$ perl -e '{ for (my $i=0; $i<3; $i++) {
my $re = qr{$i}ix; $s="123"; $s =~ s/$re//;
print "i=$i; s=$s\n"; }}'
i=0; s=123
i=1; s=23
i=2; s=13