この質問は、この他の質問に触発されています。
比較:前者はキャプチャグループを使用s/,(\d)/$1/
しs/,(?=\d)//
て数字のみを置き換え、コンマは置き換えません。後者は先読みを使用して、コンマの後に数字が続くかどうかを判断します。この回答で説明されているように、なぜ後者の方が速いのですか?
この質問は、この他の質問に触発されています。
比較:前者はキャプチャグループを使用s/,(\d)/$1/
しs/,(?=\d)//
て数字のみを置き換え、コンマは置き換えません。後者は先読みを使用して、コンマの後に数字が続くかどうかを判断します。この回答で説明されているように、なぜ後者の方が速いのですか?
2 つのアプローチは異なることを行い、異なる種類のオーバーヘッド コストを伴います。キャプチャするとき、perl はキャプチャしたテキストのコピーを作成する必要があります。消費せずに先読み一致。開始位置をマークする必要があります。re 'debug'
プラグマを使用すると、何が起こっているかを確認できます。
use re 'debug';
my $capture = qr/,(\d)/;
REx ",(\d)" をコンパイルしています 最終プログラム: 1: 正確 (3) 3: OPEN1 (5) 5: 数字 (6) 6: クローズ1 (8) 8: 終了 (0) 固定 "," at 0 (固定をチェック) minlen 2 REx の解放: ",(\d)"
use re 'debug';
my $lookahead = qr/,(?=\d)/;
REx ",(?=\d)" のコンパイル 最終プログラム: 1: 正確 (3) 3: IFMATCH[0] (8) 5: 数字 (6) 6: サクシード (0) 7: しっぽ (8) 8: 終了 (0) 固定 "," at 0 (固定をチェック) minlen 1 REx の解放: ",(?=\d)"
ほとんどの場合、先読みはキャプチャよりも高速であると予想されますが、他のスレッドで述べたように、正規表現のパフォーマンスはデータに依存する可能性があります。
いつものように、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がすでに彼のコメントで説明しているように、それは確かにそれほど驚くべきことではありません。
よろしく、マティアス