この質問は、this other oneに触発されています。キャプチャより先読み(時には)が早いのはなぜですか?
s/,(\d)/$1/
とs/,(?=\d)//
を比較すると、前者はカンマではなく数字のみを置換するためにキャプチャグループを使用します。後者はカンマが数字で後続するかどうかを判断するために先読みを使用します。 this answerで議論されているように、なぜ後者がより高速になるのでしょうか?
この質問は、this other oneに触発されています。キャプチャより先読み(時には)が早いのはなぜですか?
s/,(\d)/$1/
とs/,(?=\d)//
を比較すると、前者はカンマではなく数字のみを置換するためにキャプチャグループを使用します。後者はカンマが数字で後続するかどうかを判断するために先読みを使用します。 this answerで議論されているように、なぜ後者がより高速になるのでしょうか?
2つのアプローチは異なることを行い、さまざまな種類の間接費があります。キャプチャするとき、perlはキャプチャされたテキストのコピーを作成する必要があります。先読みは消費せずにマッチします。それが始まる場所をマークしなければならない。あなたはre 'debug'
プラグマを使用して何が起こっているかを見ることができます。
use re 'debug';
my $capture = qr/,(\d)/;
Compiling REx ",(\d)" Final program: 1: EXACT (3) 3: OPEN1 (5) 5: DIGIT (6) 6: CLOSE1 (8) 8: END (0) anchored "," at 0 (checking anchored) minlen 2 Freeing REx: ",(\d)"
use re 'debug';
my $lookahead = qr/,(?=\d)/;
Compiling REx ",(?=\d)" Final program: 1: EXACT (3) 3: IFMATCH[0] (8) 5: DIGIT (6) 6: SUCCEED (0) 7: TAIL (8) 8: END (0) anchored "," at 0 (checking anchored) minlen 1 Freeing REx: ",(?=\d)"
私は先読みは、ほとんどの場合、キャプチャするよりも高速であることを期待するが、他のスレッドで述べたように思います正規表現のパフォーマンスはデータに依存する可能性があります。
私は 're'プラグマについて考えていたはずです。ありがとう! – mpe
いつものように、あなたがより速く動作するコードの2枚のどちらかを知りたいとき、あなたはそれをテストする必要があります。
#!/usr/bin/perl
use 5.012;
use warnings;
use Benchmark qw<cmpthese>;
say "Extreme ,,,:";
my $Text = ',' x (my $LEN = 512);
cmpthese my $TIME = -10, my $CMP = {
capture => \&capture,
lookahead => \&lookahead,
};
say "\nExtreme ,0,0,0:";
$Text = ',0' x $LEN;
cmpthese $TIME, $CMP;
my $P = 0.01;
say "\nMixed (@{[$P * 100]}% zeros):";
my $zeros = $LEN * $P;
$Text = ',' x ($LEN - $zeros) . ',0' x $zeros;
cmpthese $TIME, $CMP;
sub capture {
local $_ = $Text;
s/,(\d)/$1/;
}
sub lookahead {
local $_ = $Text;
s/,(?=\d)//;
}
ベンチマークは、3つの異なる例をテスト:のみ
私のマシン上で、私のPerlのバージョンと、それはこれらの結果を生成します。
Extreme ,,,:
Rate capture lookahead
capture 23157/s -- -1%
lookahead 23362/s 1% --
Extreme ,0,0,0:
Rate capture lookahead
capture 419476/s -- -65%
lookahead 1200465/s 186% --
Mixed (1% zeros):
Rate capture lookahead
capture 22013/s -- -4%
lookahead 22919/s 4% --
これらの結果は、先読みのバージョンはほとんど唯一のカンマの場合を除き、キャプチャよりもはるかに高速であるという仮定を裏付けます。 PSIAltがすでに彼のコメントで説明したように、それは本当に驚くべきことではありません。 2つの正規表現にいくつかのベンチマークテストを行う
に関しては、 マティアス
質問は速いのではなく、_why_です。 –
私はこれをテストする方法を知っており、実際には自分自身で行っています。しかし、実証してくれてありがとう。あなたの結果は非常に説明的です! – mpe
私は本当にすべての偉大な差を決定することはできません。どちらも非常に高速です。これらの正規表現には適用されますが、先読みをキャプチャしないことに注意してください。 – TLP
明白な:データをコピーするためにグループを強制的に取り込み、次に置き換えるには '$ 1'の補間が必要ですが、2番目の正規表現は単にfind/check/removeです。しかし、速度の違いは見えないはずです。 – PSIAlt