亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

什么更快:in_array或isset?

什么更快:in_array或isset?

尚方寶劍之說 2019-11-14 09:44:35
這個問題對我來說只是個問題,因為我一直喜歡編寫優化的代碼,這些代碼也可以在廉價的慢速服務器(或具有大量流量的服務器)上運行我環顧四周,卻找不到答案。我想知道在這兩個示例之間有什么更快的方法,請記住在我的情況下數組的鍵并不重要(自然是偽代碼):<?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)
查看完整描述

3 回答

?
慕運維8079593

TA貢獻1876條經驗 獲得超5個贊

哪個更快:isset()vsin_array()


isset() 是比較快的。


顯而易見,isset()僅測試單個值。而in_array()將遍歷整個數組,測試每個元素的值。


粗略的基準測試很容易使用microtime()。


結果:

Total time isset():    0.002857

Total time in_array(): 0.017103

注意:無論是否存在,結果都是相似的。


碼:

<?php

$a = array();

$start = microtime( true );


for ($i = 0; $i < 10000; ++$i) {

    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) {

    in_array('key', $a);

}


$total_time = microtime( true ) - $start;

echo "Total time: ", number_format($total_time, 6), PHP_EOL;


exit;


查看完整回答
反對 回復 2019-11-14
?
慕婉清6462132

TA貢獻1804條經驗 獲得超2個贊

使用isset()可以提高查找速度,因為它使用哈希表,從而避免了O(n)搜索。


首先使用djb哈希函數對密鑰進行哈希處理,以確定中類似哈希密鑰的存儲桶O(1)。然后重復搜索該存儲桶,直到在中找到確切的密鑰O(n)。


除非有任何有意的哈希沖突,這種方法產生的性能要比更好in_array()。


請注意,isset()按照顯示的方式使用時,將最終值傳遞給另一個函數需要使用array_keys()創建一個新數組。通過將數據存儲在鍵和值中,可能會造成內存折衷。


更新資料


查看代碼設計決策如何影響運行時性能的好方法,可以查看腳本的編譯版本:


echo isset($arr[123])


compiled vars:  !0 = $arr

line     # *  op                           fetch      ext  return  operands

-----------------------------------------------------------------------------

   1     0  >   ZEND_ISSET_ISEMPTY_DIM_OBJ              2000000  ~0      !0, 123

         1      ECHO                                                 ~0

         2    > RETURN                                               null

echo in_array(123, $arr)


compiled vars:  !0 = $arr

line     # *  op                           fetch      ext  return  operands

-----------------------------------------------------------------------------

   1     0  >   SEND_VAL                                             123

         1      SEND_VAR                                             !0

         2      DO_FCALL                                 2  $0      'in_array'

         3      ECHO                                                 $0

         4    > RETURN                                               null

不僅in_array()使用效率相對較低的O(n)搜索,還需要將其稱為函數(DO_FCALL),而為此isset()使用單個操作碼(ZEND_ISSET_ISEMPTY_DIM_OBJ)。


查看完整回答
反對 回復 2019-11-14
  • 3 回答
  • 0 關注
  • 849 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號