はじめに
前回に引き続き,PHP最適化Tipsについて検証していきます。
今回は文字列置換関数の比較です。またgdbを用いたPHPコードの読み方についても紹介します。
strtr > str_replace > preg_replace の順に速い
この3つの関数は細かな動きに違いはあるものの,文字列を置き換える関数です。このように同じ動きをする関数が多く存在するのは良くも悪くもPHPの特徴であるといえます。
下記のベンチマーク用のコードを用意して,計測を行います。
benchmark_strtr.php
<?php
$t = microtime(true);
$i = 0;
while($i < 1000) {
$a = strtr('abcdefghijklmn', 'abc', 'ABC');
++$i;
}
$tmp = microtime(true) - $t;
var_dump($tmp);
?>
benchmark_strreplace.php
<?php
$t = microtime(true);
$i = 0;
while ($i < 1000) {
$a = str_replace('abc', 'ABC', 'abcdefghijklmn');
++$i;
}
$tmp = microtime(true) - $t;
var_dump($tmp);
?>
benchmark_pregreplace.php
<?php
$t = microtime(true);
$i = 0;
while ($i < 1000) {
$a = preg_replace('/abc/', 'ABC', 'abcdefghijklmn');
++$i;
}
$tmp = microtime(true) - $t;
var_dump($tmp);
?>
$ php benchmark_strtr.php float(0.000890970230103) $ php benchmark_strreplace.php float(0.000858068466187) $ php benchmark_pregreplace.php float(0.00124001502991)
実行結果は上記のようになりました。 strtrとstr_replaceはほぼ同じくらいの速さ,preg_replaceは明らかに遅い結果になりました。
strtrとstr_replaceについて,性質上どのような違いがあるのか解説したいと思います。 strtrはext/standard/string.cのPHP_FUNCTION(strtr)で定義されており,php_strtrで文字列の置き換えが行われています。
2804 PHP_FUNCTION(strtr)
中略
2825 if (ac == 2) {
2826 php_strtr_array(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), HASH_OF(*from));
2827 } else {
2828 convert_to_string_ex(from);
2829 convert_to_string_ex(to);
2830
2831 ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);
2832
2833 php_strtr(Z_STRVAL_P(return_value),
2834 Z_STRLEN_P(return_value),
2835 Z_STRVAL_PP(from),
2836 Z_STRVAL_PP(to),
2837 MIN(Z_STRLEN_PP(from),
2838 Z_STRLEN_PP(to)));
2839 }
2840 }
PHP_FUNCTION(strtr)では,引数のvalidationと与えられた引数が配列かどうかによって置換する関数を振り分けます。 引数に文字列を与えた場合は,2833行目のphp_strtrが実行されます。

