文字列連結のパフォーマンス比較
そういえば計ったことなかったなぁ‥と思い立って、いくつかのパターンで計ってみたメモ。
実行環境は、自宅のXenServer上に載せた以下のVM環境。
ケース1:文字列連結演算子とダブルクォーテーションと
プログラムの全体は以下のような感じ。
n,test1,test2 <?php for ($n = 10000; $n <= 50000; $n += 5000) { set_time_limit(120); // test1 $s1 = microtime(true); $str = ''; for ($i = 0; $i < $n; ++$i) { $str = $str . 'a' . $i . 'b'; } $e1 = microtime(true); // test2 $s2 = microtime(true); $str = ''; for ($i = 0; $i < $n; ++$i) { $str = "{$str}a{$i}b"; } $e2 = microtime(true); printf("%d,%.3f,%.3f\n", $n, $e1 - $s1 , $e2 - $s2); }
文字列を
$str = $str . 'a' . $i . 'b';
で連結するか
$str = "{$str}a{$i}b";
で連結するかの違い。
実行すると、以下のような出力が得られる。
n,test1,test2 10000,0.075,0.029 15000,0.228,0.065 20000,0.445,0.120 25000,0.873,0.199 30000,1.422,0.300 35000,2.168,0.451 40000,3.023,0.581 45000,2.802,0.739 50000,3.962,0.938
グラフにしてみるとこんな感じ。
ケース2:ダブルクォーテーションと複合演算子と
プログラムの全体は以下のような感じ。
n,test2,test3,test4 <?php for ($n = 10000; $n <= 100000; $n += 5000) { set_time_limit(120); // test2 $s2 = microtime(true); $str = ''; for ($i = 0; $i < $n; ++$i) { $str = "{$str}a{$i}b"; } $e2 = microtime(true); // test3 $s3 = microtime(true); $str = ''; for ($i = 0; $i < $n; ++$i) { $str .= 'a' . $i . 'b'; } $e3 = microtime(true); // test4 $s4 = microtime(true); $str = ''; for ($i = 0; $i < $n; ++$i) { $str .= "a{$i}b"; } $e4 = microtime(true); printf("%d,%.3f,%.3f,%.3f\n", $n, $e2 - $s2, $e3 - $s3, $e4 - $s4); }
文字列を
$str = "{$str}a{$i}b";
$str .= 'a' . $i . 'b';
$str .= "a{$i}b";
のように連結するという3パターン。1つ目は、ケース1で早かった方と同じ。
実行すると、以下のような出力が得られる。
n,test2,test3,test4 10000,0.016,0.001,0.001 15000,0.034,0.002,0.002 20000,0.069,0.003,0.003 25000,0.102,0.004,0.003 30000,0.149,0.004,0.004 35000,0.210,0.005,0.005 40000,0.281,0.006,0.005 45000,0.363,0.006,0.006 50000,0.455,0.007,0.007 55000,0.556,0.008,0.008 60000,0.668,0.009,0.008 65000,0.782,0.009,0.009 70000,0.916,0.010,0.009 75000,1.054,0.011,0.011 80000,1.212,0.011,0.011 85000,1.364,0.012,0.012 90000,1.534,0.013,0.012 95000,1.723,0.013,0.013 100000,1.915,0.014,0.014
‥圧倒的差である。一応グラフにしてみる。
test3のグラフは隠れて見えないが、test4の下に隠れている。
結局‥
- ケース2の結果を見る限り、長い文字列
$str
が右辺に出てくるときの評価にコストがかかるのだろうか。 - ケース1の結果から、同じ長い文字列が右辺に現れざるを得ない場合は、文字列連結演算子の処理の方がコストがかかるということか。
正直、ここまで差が出るとは思わなかったので、文字列連結処理を書くときには、これからは気を使うようにしようと思う。