数组是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