數組是PHP的一個大殺器. 如何判斷一個大數組中是否存在某一個值, 需要考慮性能問題. 對於小的數組, 我們可以直接使用 in_array
, 那麼大點的數組就需要使用array_flip反轉鍵值對, 然後使用 array_key_exists或者isset了.
測試環境: win10 + PHP 7.2.0 (Cli)
先準備一個10w的數組, 以及一個要查找的值, 然後循環查找1w次, 記錄時間.
這裏我們用短md5的方式生成數組的值)
function md5short($id) {
return substr(md5($id), 8, 16);
}
//一個10w的數組
$arrLarge = [];
for ($i = 0; $i < 100000; $i++) {
$arrLarge[$i] = md5short($i);
}
//要查找的值
$needle = md5short(99998); //682d83a41d25acb6
in_array
的測試代碼:
//in_array 用時計算
$timeStart = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$rt = in_array($needle, $arrLarge);
}
$timeEnd = microtime(true);
$timeElapsed = round($timeEnd - $timeStart, 6) * 1000;
echo 'in_array 1000次用時 ' . $timeElapsed . ' ms' . PHP_EOL . PHP_EOL;
array_key_exits
的測試代碼:
//array_key_exists 用時計算
//交換鍵和值
$timeStart = microtime(true);
$arrLargeFlipped = array_flip($arrLarge);
$timeEnd = microtime(true);
$timeElapsed = round($timeEnd - $timeStart, 6) * 1000;
echo '交換鍵和值一次 用時 ' . $timeElapsed . ' ms' . PHP_EOL;
$timeStart = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$rt = array_key_exists($needle, $arrLarge);
}
$timeEnd = microtime(true);
$timeElapsed = round($timeEnd - $timeStart, 6) * 1000;
echo 'array_key_exists 1000次用時 ' . $timeElapsed . ' ms' . PHP_EOL;
isset
的測試代碼:
//isset 用時計算
//交換鍵和值
$timeStart = microtime(true);
$arrLargeFlipped2 = array_flip($arrLarge);
$timeEnd = microtime(true);
$timeElapsed = round($timeEnd - $timeStart, 6) * 1000;
echo '交換鍵和值一次 用時 ' . $timeElapsed . ' ms' . PHP_EOL;
$timeStart = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$rt = isset($arrLarge[$needle]);
}
$timeEnd = microtime(true);
$timeElapsed = round($timeEnd - $timeStart, 6) * 1000;
echo 'isset 1000次用時 ' . $timeElapsed . ' ms' . PHP_EOL;
測試結果1:
in_array 1000次用時 17763.025 ms
交換鍵和值一次 用時 5.54 ms
array_key_exists 1000次用時 0.52 ms
交換鍵和值一次 用時 3.746 ms
isset 1000次用時 0.357 ms
測試結果2:
in_array 1000次用時 17495.181 ms
交換鍵和值一次 用時 4.871 ms
array_key_exists 1000次用時 0.543 ms
交換鍵和值一次 用時 3.956 ms
isset 1000次用時 0.41 ms
有結果可知, 在大數組的情況下, in_array的速很慢, 不考慮鍵值互換消耗的時間, array_key_exists和isset的速速是極快的.
三者的性能關係:
isset > array_key_exists >> in_array