在處理大量資料的 PHP 專案中,陣列操作效能往往成為瓶頸。本文透過實測數據,深度解析 in_array 與 isset、array_unique 與 array_flip 兩組經典方案的效能差異,助你在百萬級資料量下做出正確選擇。
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
$needle:待搜尋的值,字串比較區分大小寫$haystack:目標陣列$strict:若為 TRUE 則同時檢查型別<?php
$arr = array();
for($i=0; $i<100000; $i++){ $arr[] = $i; }
$starttime = getMicrotime();
for($j=0; $j<1000; $j++){
$str = mt_rand(1,99999);
in_array($str, $arr);
}
$endtime = getMicrotime();
echo 'run time:'.(float)(($endtime-$starttime)*1000).'ms<br>';
function getMicrotime(){
list($usec, $sec) = explode(' ', microtime());
return (float)$usec + (float)$sec;
}
?>
結果:約 2003 毫秒(2 秒)
原因在於 in_array 採用線性搜尋,時間複雜度 O(n),資料量增長時效能呈指數級下降。
PHP 陣列底層為雜湊表,鍵值查找 isset($arr[$key]) 為 O(1) 操作。利用 array_flip 將「值」轉為「鍵」,即可獲得極速查找能力。
<?php
$arr = array();
for($i=0; $i<100000; $i++){ $arr[] = $i; }
// 關鍵步驟:鍵值互換
$arr = array_flip($arr);
$starttime = getMicrotime();
for($j=0; $j<1000; $j++){
$str = mt_rand(1,99999);
isset($arr[$str]);
}
$endtime = getMicrotime();
echo 'run time:'.(float)(($endtime-$starttime)*1000).'ms<br>';
?>
結果:約 1.28 毫秒
效能提升:1500 倍以上!
array_flip 會移除重複值(後者覆蓋前者),若原陣列有重複值需評估影響$arr = array(1,1,2,3,3,3,4,4,5,6,6,7,8,8,9,9,9); $arr = array_unique($arr); $arr = array_values($arr); // 重新索引
輸出:Array ( [0] => 1 [1] => 2 [2] => 3 ... )
<?php
$arr = array();
for($i=0; $i<100000; $i++){ $arr[] = mt_rand(1,99); }
$starttime = getMicrotime();
$arr = array_unique($arr);
$endtime = getMicrotime();
$arr = array_values($arr);
echo 'unique count:'.count($arr).'<br>';
echo 'run time:'.(float)(($endtime-$starttime)*1000).'ms<br>';
echo 'use memory:'.getUseMemory();
function getUseMemory(){
return round(memory_get_usage(true)/1024,2).'kb';
}
?>
結果:約 653 毫秒,記憶體 5120 KB
$arr = array_flip($arr); // 值→鍵,自動去重 $arr = array_flip($arr); // 鍵→值,恢復原結構 $arr = array_values($arr); // 重新索引
結果:約 12.8 毫秒,記憶體 768 KB
| 指標 | array_unique | array_flip×2 | 提升幅度 |
|---|---|---|---|
| 執行時間 | 653 ms | 12.8 ms | 98% ↓ |
| 記憶體佔用 | 5120 KB | 768 KB | 85% ↓ |
array_flip 原地操作,無額外大型臨時結構array_flip 快取,查找用 issetarray_flip 雙重翻轉array_intersect_key 回溯__toString 或使用 spl_object_id 作為鍵PHP 陣列底層為有序雜湊表,善用「鍵值互換」思維,能將 O(n) 或 O(n log n) 操作降為 O(1) 或 O(n),在大資料場景下效能差異可達數量級。實務上建議封裝為工具類方法,如 ArrayUtil::fastInArray()、ArrayUtil::fastUnique(),統一團隊開發標準。