什么更快:in_array或isset?

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


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


<?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攻击(http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html)


尚方宝剑之说
浏览 782回答 3
3回答

慕运维8079593

哪个更快:isset()vsin_array()isset() 是比较快的。显而易见,isset()仅测试单个值。而in_array()将遍历整个数组,测试每个元素的值。粗略的基准测试很容易使用microtime()。结果:Total time isset():&nbsp; &nbsp; 0.002857Total time in_array(): 0.017103注意:无论是否存在,结果都是相似的。码:<?php$a = array();$start = microtime( true );for ($i = 0; $i < 10000; ++$i) {&nbsp; &nbsp; isset($a['key']);}$total_time = microtime( true ) - $start;echo "Total time: ", number_format($total_time, 6), PHP_EOL;$start = microtime( true );for ($i = 0; $i < 10000; ++$i) {&nbsp; &nbsp; in_array('key', $a);}$total_time = microtime( true ) - $start;echo "Total time: ", number_format($total_time, 6), PHP_EOL;exit;

慕婉清6462132

使用isset()可以提高查找速度,因为它使用哈希表,从而避免了O(n)搜索。首先使用djb哈希函数对密钥进行哈希处理,以确定中类似哈希密钥的存储桶O(1)。然后重复搜索该存储桶,直到在中找到确切的密钥O(n)。除非有任何有意的哈希冲突,这种方法产生的性能要比更好in_array()。请注意,isset()按照显示的方式使用时,将最终值传递给另一个函数需要使用array_keys()创建一个新数组。通过将数据存储在键和值中,可能会造成内存折衷。更新资料查看代码设计决策如何影响运行时性能的好方法,可以查看脚本的编译版本:echo isset($arr[123])compiled vars:&nbsp; !0 = $arrline&nbsp; &nbsp; &nbsp;# *&nbsp; op&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fetch&nbsp; &nbsp; &nbsp; ext&nbsp; return&nbsp; operands-----------------------------------------------------------------------------&nbsp; &nbsp;1&nbsp; &nbsp; &nbsp;0&nbsp; >&nbsp; &nbsp;ZEND_ISSET_ISEMPTY_DIM_OBJ&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2000000&nbsp; ~0&nbsp; &nbsp; &nbsp; !0, 123&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1&nbsp; &nbsp; &nbsp; ECHO&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;~0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2&nbsp; &nbsp; > RETURN&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nullecho in_array(123, $arr)compiled vars:&nbsp; !0 = $arrline&nbsp; &nbsp; &nbsp;# *&nbsp; op&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fetch&nbsp; &nbsp; &nbsp; ext&nbsp; return&nbsp; operands-----------------------------------------------------------------------------&nbsp; &nbsp;1&nbsp; &nbsp; &nbsp;0&nbsp; >&nbsp; &nbsp;SEND_VAL&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;123&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1&nbsp; &nbsp; &nbsp; SEND_VAR&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2&nbsp; &nbsp; &nbsp; DO_FCALL&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2&nbsp; $0&nbsp; &nbsp; &nbsp; 'in_array'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3&nbsp; &nbsp; &nbsp; ECHO&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4&nbsp; &nbsp; > RETURN&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;null不仅in_array()使用效率相对较低的O(n)搜索,还需要将其称为函数(DO_FCALL),而为此isset()使用单个操作码(ZEND_ISSET_ISEMPTY_DIM_OBJ)。
打开App,查看更多内容
随时随地看视频慕课网APP