現在、PHP 5.2.17 用に書かれた非常に古いスクリプトを PHP 8.1.2 用に更新しています。多くのテキスト処理コード ブロックがあり、そのほとんどが preg_match/preg_match_all です。文字列マッチングの strpos は常に preg_match よりも高速であることは以前から知っていましたが、もう一度確認することにしました。
コードは次のとおりです。
$c = file_get_contents('readme-redist-bins.txt');
$start = microtime(true);
for ($i=0; $i < 1000000; $i++) {
strpos($c, '[SOMEMACRO]');
}
$el = microtime(true) - $start;
exit($el);
と
$c = file_get_contents('readme-redist-bins.txt');
$start = microtime(true);
for ($i=0; $i < 1000000; $i++) {
preg_match_all("/\[([a-z0-9-]{0,100})".'[SOMEMACRO]'."/", $c, $pma);
}
$el = microtime(true) - $start;
exit($el);
php8.1.2 ディストリビューションに付属する readme-redist-bins.txt ファイル、約 30KB を取得しました。
結果 (preg_match_all):
PHP_8.1.2: 1.2461s
PHP_5.2.17: 11.0701s
結果 (strpos):
PHP_8.1.2: 9.97s
PHP_5.2.17: 0.65s
ダブルチェック... 2台のマシンでWindowsとLinuxのPHPビルドを試しました。
小さなファイル(200B)で同じコードを試しました
結果 (preg_match_all):
PHP_8.1.2: 0.0867s
PHP_5.2.17: 0.6097s
結果 (strpos):
PHP_8.1.2: 0.0358s
PHP_5.2.17: 0.2484s
そして今、タイミングはOKです。
では、preg_match が大きなテキストでより速く一致するというのは、どうしてでしょうか? 何か案は?
PS: PHP_7.2.10 を試してみました - 同じ結果です。