2012-12-03 4 views
7

この質問は、this other oneに触発されています。キャプチャより先読み(時には)が早いのはなぜですか?

s/,(\d)/$1/s/,(?=\d)//を比較すると、前者はカンマではなく数字のみを置換するためにキャプチャグループを使用します。後者はカンマが数字で後続するかどうかを判断するために先読みを使用します。 this answerで議論されているように、なぜ後者がより高速になるのでしょうか?

+1

私は本当にすべての偉大な差を決定することはできません。どちらも非常に高速です。これらの正規表現には適用されますが、先読みをキャプチャしないことに注意してください。 – TLP

+4

明白な:データをコピーするためにグループを強制的に取り込み、次に置き換えるには '$ 1'の補間が必要ですが、2番目の正規表現は単にfind/check/removeです。しかし、速度の違いは見えないはずです。 – PSIAlt

答えて

4

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)" 

私は先読みは、ほとんどの場合、キャプチャするよりも高速であることを期待するが、他のスレッドで述べたように思います正規表現のパフォーマンスはデータに依存する可能性があります。

+0

私は 're'プラグマについて考えていたはずです。ありがとう! – mpe

-1

いつものように、あなたがより速く動作するコードの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つの異なる例をテスト:のみ

  1. 」を、 '
  2. のみ
  3. '、0'
  4. 1% '0' 、残りの部分'、」

私のマシン上で、私の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つの正規表現にいくつかのベンチマークテストを行う

に関しては、 マティアス

+1

質問は速いのではなく、_why_です。 –

+0

私はこれをテストする方法を知っており、実際には自分自身で行っています。しかし、実証してくれてありがとう。あなたの結果は非常に説明的です! – mpe

関連する問題