[正規表現] 分岐は遅い

正規表現では、「分岐」は遅いです。「a又はb又はcのいずれかにマッチ」する正規表現であれば、(a|b|c)よりも、[abc]の方が確実に速いです。

このことは、PHPマニュアルにも記載されています

実際にどのくらいの差があるのか、見てみましょう。
(ベンチマーク用の正規表現は、404 Blog Not Found:perl – 自動で /a|b|c/ を /[abc]/ にしてくれたら…を参考にしました)

<?php
$re_alt    = '/s|t|u|v|w|x|y|z/';
$re_cclass = '/[stuvwxyz]/';
$alphabets = 'abcdefghijklmnopqrstuvwxyz';
$ntimes = 100000;
$start = microtime(true) * 1000;
for ($i = $ntimes; $i > 0; $i--) {
preg_match($re_alt, $alphabets);
}
$end = microtime(true) * 1000;
var_dump($end - $start); // 分岐:約0.30秒
$start = microtime(true) * 1000;
for ($i = $ntimes; $i > 0; $i--) {
preg_match($re_cclass, $alphabets);
}
$end = microtime(true) * 1000;
var_dump($end - $start); // 文字クラス:約0.14秒

PHP Sandboxで実際に実行できますが、実行時間には2倍~3倍程度の差がつきます。

ただし、言語によっては、正規表現エンジンが正規表現の最適化を行ってくれます。実際、Ruby 2.0.0で上記例と同様の正規表現を実行すると、ほとんど差がありません。

残念ながら、PHPでは今のところ正規表現の最適化は自動で行われません。手動で最適化を行う必要があります。

PerlのRegexp::AssembleのPHP移植版もあるみたいなので、この辺使うと良いかも。

コメントをどうぞ

コメントを残す