一尘不染

什么更快:in_array或isset?

php

这个问题对我来说只是个问题,因为我一直喜欢编写优化的代码,这些代码也可以在廉价的慢速服务器(或具有大量流量的服务器)上运行

我环顾四周,却找不到答案。我想知道在这两个示例之间有什么更快的方法,请牢记在我的案例中数组的键并不重要(自然是伪代码):

<?php
$a = array();
while($new_val = 'get over 100k email addresses already lowercased'){
    if(!in_array($new_val, $a){
        $a[] = $new_val;
        //do other stuff
    }
}
?>

<?php
$a = array();
while($new_val = 'get over 100k email addresses already lowercased'){
    if(!isset($a[$new_val]){
        $a[$new_val] = true;
        //do other stuff
    }
}
?>

因为问题的关键不是数组冲突,所以我想补充一点,如果您担心冲突的插入$a[$new_value],可以使用$a[md5($new_value)]。它仍然可能导致冲突,但是当从用户提供的文件中读取时,它可以避免可能的DoS攻击


阅读 356

收藏
2020-05-26

共1个答案

一尘不染

到目前为止,答案是确定的。isset在这种情况下使用速度更快,因为

  • 它在键上使用O(1)哈希搜索,而in_array必须检查每个值,直到找到匹配项。
  • 作为操作码,它比调用in_array内置函数的开销少。

这些可以通过使用具有值的数组(在下面的测试中为10,000)来证明,这需要进行in_array更多的搜索。

isset:    0.009623
in_array: 1.738441

通过填写一些随机值并偶尔查找数组中存在的值,以此建立了Jason的基准。都是随机的,所以要注意时间会波动。

$a = array();
for ($i = 0; $i < 10000; ++$i) {
    $v = rand(1, 1000000);
    $a[$v] = $v;
}
echo "Size: ", count($a), PHP_EOL;

$start = microtime( true );

for ($i = 0; $i < 10000; ++$i) {
    isset($a[rand(1, 1000000)]);
}

$total_time = microtime( true ) - $start;
echo "Total time: ", number_format($total_time, 6), PHP_EOL;

$start = microtime( true );

for ($i = 0; $i < 10000; ++$i) {
    in_array(rand(1, 1000000), $a);
}

$total_time = microtime( true ) - $start;
echo "Total time: ", number_format($total_time, 6), PHP_EOL;
2020-05-26