#数字を補足する正規表現$NUMBERを作成する
Readonly my $DIGITS => qr{ \d+ (?: [.] \d*)? | [.] \d+ }xms;
Readonly my $SIGN => qr{ [+-] }xms;
Readonly my $EXPONENT => qr{ [Ee] $SIGN? \d+ }xms;
Readonly my $NUMBER => qr{ ( ($SIGN?) ($DIGITS) ($EXPONENT?) ) }xms;
このネストが、なぜ遅いのか理解できました。
まず、なぜ理解できなかったのかというと、$DIGITS => qr{ ... } の時点で、$DIGITSにはプリコンパイルされた値が入っているというのが分かってなかったからです。
$NUMBERで使用している$DIGITSなどはすでにコンパイルされているので、これを逆コンパイルして、文字列にもどしてから、$NUMBERに代入される正規表現全体で再度コンパイルしています。
「逆コンパイル」ということは、そりゃぁ、元の文字列にならないこともあるよなぁ、という感じです。
Deparseしたら見れるのかな?と思って
$perl -MO=Deparse,-x7 qr.pl
としてみたけど。特に何も見れませんでした。
ついでに以下ような変換が見れました。
#before
if(A =~ B){ ... }
#after
A =~ B and do{ ... }
#before
for (my $i=0; $i<10; $i++) {
$i++;
}
#after
while ($i < 10) {
++$i;
}
continue {
++$i
}
初めcontinueは何だろうと思ったけれど、forはブロックの最後に反復子がインクリメントされるから最後に1回だけインクリメントしないといけないですよね。
面白いなぁ。
0 件のコメント:
コメントを投稿