条件式の省略化時の速度
mixiの [Let's PHP] トピックで、ある変数が「1」か「2」か「3」か「4」か「5」か「6」の時に何かする場合の条件式の書き方の話が出ていた。そこに、僕は、isset()を使うとちょっと速いという件を書き込んだ。というわけで、ベンチマークをしてみる。
function mtime_diff($a, $b) { list($a_dec, $a_sec) = explode(' ', $a); list($b_dec, $b_sec) = explode(' ', $b); return $b_sec - $a_sec + $b_dec - $a_dec; } $nums = array(); for ($i=0; $i<10000; $i++) { $nums[] = mt_rand(1,20); } $st = microtime(); $ret = 0; foreach ($nums as $num) { if ($num == 1 || $num == 2 || $num == 3 || $num == 4 || $num == 5 || $num == 6) { $ret += 1; } } echo sprintf("%0.5f <br>", mtime_diff($st, microtime())); $st = microtime(); $ret = 0; foreach ($nums as $num) { switch ($num) { case 1: case 2: case 3: case 4: case 5: case 6: $ret += 1; } } echo sprintf("%0.5f <br>", mtime_diff($st, microtime())); $st = microtime(); $chk = array(1,2,3,4,5,6); $ret = 0; foreach ($nums as $num) { if (in_array($num, $chk)) { $ret += 1; } } echo sprintf("%0.5f <br>", mtime_diff($st, microtime())); $st = microtime(); $chk2 = array(1 =>1 ,2=>1 ,3=>1 ,4=>1 ,5=>1 ,6=>1 ); $ret = 0; foreach ($nums as $num) { if (isset($chk2[$num])) { $ret += 1; } } echo sprintf("%0.5f <br>", mtime_diff($st, microtime())); $st = microtime(); $chk3 = array(1 =>1 ,2=>1 ,3=>1 ,4=>1 ,5=>1 ,6=>1 ); $ret = 0; foreach ($nums as $num) { if ($chk3[$num]) { $ret += 1; } } echo sprintf("%0.5f <br>", mtime_diff($st, microtime())); $st = microtime(); $chk4 = array(1 =>1 ,2=>1 ,3=>1 ,4=>1 ,5=>1 ,6=>1 ); $ret = 0; foreach ($nums as $num) { if (@$chk4[$num]) { $ret += 1; } } echo sprintf("%0.5f <br>", mtime_diff($st, microtime()));
結果は、自分のセレロン1GHzのwinXP_homeノート(Apache/1.3.31+PHP/4.3.7)では、
0.05237
0.04205
0.04645
0.03138
0.05120
0.09256
となった。
(1)if文べた書きより、(2)switch文および(3)in_array()方式が20%程度速く、(4)isset()方式がもっとも速く40%ほど向上。(5)選択肢の配列をそのまま書く方式は意外にも(1)if文べた書きと同程度で、念のため(6)noticeが出ないように@をつけると倍近く遅くなる。
追記:書き忘れてたけど、僕の環境ではerror_reporting(E_ALL ^ E_NOTICE)でnoticeは表示されない設定。