str_replace は strtr よりも速度が速かった(PHP)
PHP の strtr() は、str_replace() より速いって言われることがある。
確かに、昔、おいらが計測した時には、strtr() の方が速かったはず。
だが、こちらの方の記事では、「そうでもない」と言っている。
strtrとstr_replaceの処理速度検証 | Fujitaiju Blog
なので、おいらも PHP5.3 と PHP5.6 で計測しなおしてみた。
どんな条件で何回やっても、str_replace() の方が速かった
PHP: strtr – Manual にも書いてある通り、strtr() が最大の真価を発揮するのは、
すべてのキーが同じ長さの場合 である。
なので、まず、この条件でやってみる。
全てのキーが同じ長さの場合
$before = array();
$after = array();
for( $i = 0; 100000 > $i; $i++ ) {
$before[] = 'abcde';
}
strtr()
foreach( $before as $value ) {
$after[] = strtr( $value, 'abcde', '12345' );
}
0.0570030212 sec(平均:0.057 ~ 0.061 sec)
何度やっても、0.057 sec の壁が破れない。
str_replace()
foreach( $before as $value ) {
$after[] = str_replace( 'abcde', '12345', $value );
}
0.0540039539 sec(平均:0.054 ~ 0.059 sec)
たまに、strtr() に負けるが、平均では str_replace() の方が速い。
キーと値を任意の長さにした場合
strtr() は、引数を配列にして、二つだけ渡した場合、キーと値を任意の長さにして、
str_replace() とほぼ同等のことができるようになる。
なので、このパターンを検証してみる。
strtr()
$replace = array( 'abcde' => '123456789' );
foreach( $before as $value ) {
$after[] = strtr( $value, $replace );
}
0.3850221634 sec(平均:0.385 ~ 0.396 sec)
遅っそ・・・ (´Д`)
str_replace()
foreach( $before as $value ) {
$after[] = str_replace( 'abcde', '123456789', $value );
}
0.0531030727 sec(平均:0.053 ~ 0.062 sec)
strtr() より、約7~8倍 速い!
検証結果
全てのキーが同じ長さなら、ほとんど差がないが、むしろ str_replace() の方が微妙に速かった。
キーと値の長さが違う場合、全く比較にならないほど、str_replace() の方が速かった。
この検証結果だけで見れば、strtr() を使う理由が見当たらなくなるw
ただ、PHP は、バージョンアップを繰り返すごとに、関数も最適化されてきたので、
今後のバージョンアップで、strtr() も盛り返してくるかもしれない。
でも、現在の PHP(5.3~5.6)だと、str_replace() の方が速いっぽい。
最近、GitHub に、こんな投稿もあったが、
php最適化テクニカル · GitHub
strtr() が4倍速いとか、ありえん・・・
書き換えた方がええんちゃう?
ディスカッション
コメント一覧
かなり昔の記事へのコメントで申し訳ないんですが、全てのキーが同じ長さの場合がおかしくないでしょうか。
strtrの場合とstr_replaceの場合とでやっていることが違います。strtrの場合はa~eをそれぞれ1~5に置き換えているのに対し、str_replaceはabcdeを12345に置き換えています。
すると、速度が異なるのは当然ということになります。長さが2以上の文字列にはBoyer-Moore法のようなアルゴリズムを使えますが、長さが1の文字列には使うことができません。abcdeを12345に置換する場合、$value[4]==’e’でない場合5文字飛ばすことができます。それに対して、a~eをそれぞれ1~5に置換する場合、各文字に対して5回ずつ比較を行う必要があります。
これを考慮に入れると、配列を使わないstrtrは優秀ということにならないでしょうか。ほぼ5倍比較する必要があるにも関わらず、同じ程度の時間で済むからです。
tksm さん。
言わんとするところは分かるんです。
が、「文字列を置換する手法として、双方を比較して同じ結果を求めるなら」ってことになると、結局は str_replace って答えるしかない気がするんですよね。