array_searchとin_arrayの比較

マニュアルには

mixed array_search ( mixed needle, array haystack [, bool strict] )

bool in_array ( mixed needle, array haystack [, bool strict] )

とある。
どちらも配列の値を検索するものだが、array_searchは最初にマッチしたキーを返すのに対し、in_arrayは見つかったかどうかを真偽値で返す。array_searchは

if( array_search($needle, $haystack) == true ){...}

とすると$haystack[0]とか$haystack['']でマッチしたときも偽となるので、==ではなく===を使うべきだが(マニュアルでも警告してある)、真偽値だけがほしい場合は素直にin_arrayを使うべきだろう。
だけど、同じような機能なら速い方を使いたいのでどんなもんか調べてみた。

参考:http://jigen.aruko.net/archives/433/ preg_replaceとstr_replaceとstrtrとを比較している。
ついでにマニュアルを見ていてarray_keysというものも見つけたので、一緒に調べてみた。

array array_keys ( array input [, mixed search_value [, bool strict]] )

define('NUM', 10000);
define('BR', "\n");

for($i=0;$i<NUM;$i++){
  $array[$i] = $i;
}

$time=microtime(true);
for($i=0;$i<NUM;$i++){  array_search($i, $array);  }
$end_time=sprintf("%01.04f", microtime(true)-$time);
echo '[ '.$end_time.' sec ] [array_search]'.BR;

$time=microtime(true);
for($i=0;$i<NUM;$i++){  in_array($i, $array);  }
$end_time=sprintf("%01.04f", microtime(true)-$time);
echo '[ '.$end_time.' sec ] [in_array]'.BR;

$time=microtime(true);
for($i=0;$i<NUM;$i++){  array_keys($array, $i);  }
$end_time=sprintf("%01.04f", microtime(true)-$time);
echo '[ '.$end_time.' sec ] [array_keys]'.BR;

結果

  • WindowsXP, Celeron 3GHz, 1GB, PHP 5.2.0
    • [ 3.8817 sec ] [array_search]
    • [ 3.8603 sec ] [in_array]
    • [ 9.1067 sec ] [array_keys]
  • Linux (SuSE), Celeron 2.66GHz, 1GB, PHP 5.2.0
    • [ 3.1077 sec ] [array_search]
    • [ 3.1003 sec ] [in_array]
    • [ 7.5052 sec ] [array_keys]
  • Linux (Redhat), Pentium4 3GHz, 1GB, PHP 4.4.2
    • [ 2.5628 sec ] [array_search]
    • [ 2.5380 sec ] [in_array]
    • [ 6.4965 sec ] [array_keys]
  • Linux (CentOS), VPS (Xeon 3GHz Dual, 4GB), PHP 5.2.0
    • [ 7.5420 sec ] [array_search]
    • [ 7.4493 sec ] [in_array]
    • [ 18.8103 sec ] [array_keys]
  • array_searchとin_arrayは変わらない。
  • array_keysはとても遅い。でもこれって配列の最後まで検索しているからかな。

microtime(true)はPHP5じゃないと使えないので、PHP4ではマニュアルのコメントにあった

function microtime_float() {
  return array_sum(explode(' ',microtime()));
}

を使いました。