大數組(10萬+ 元素)頻繁查找、去重時,in_array() 和 array_unique() 性能嚴重不足。本文通過實測對比,揭示高效替代方案。
<?php
$arr = range(0, 99999); // 10萬元素
$start = microtime(true);
for ($j = 0; $j < 1000; $j++) {
$str = mt_rand(1, 99999);
in_array($str, $arr);
}
$end = microtime(true);
echo 'in_array time: ' . ($end - $start) * 1000 . ' ms';
// 結果:約 2003 ms
<?php
$arr = range(0, 99999);
$arr = array_flip($arr); // 鍵值互換,值變鍵
$start = microtime(true);
for ($j = 0; $j < 1000; $j++) {
$str = mt_rand(1, 99999);
isset($arr[$str]); // O(1) 哈希查找
}
$end = microtime(true);
echo 'isset time: ' . ($end - $start) * 1000 . ' ms';
// 結果:約 1.28 ms
| 方法 | 10萬元素/1000次查找 | 時間複雜度 | 提升倍數 |
|---|---|---|---|
| in_array() | ~2000 ms | O(n) | 基準 |
| array_flip + isset() | ~1.3 ms | O(1) | 1500x+ |
原理:PHP 數組底層是有序哈希表,鍵查找為 O(1);in_array 需遍歷值,O(n)。array_flip 將值轉為鍵,利用哈希特性。
<?php $arr = []; for ($i = 0; $i < 100000; $i++) $arr[] = mt_rand(1, 99); $start = microtime(true); $arr = array_unique($arr); $arr = array_values($arr); // 重排鍵 $end = microtime(true); echo 'array_unique: ' . ($end - $start) * 1000 . ' ms, 內存: ' . round(memory_get_usage(true)/1024, 2) . ' KB'; // 結果:~653 ms, 5120 KB
<?php $arr = []; for ($i = 0; $i < 100000; $i++) $arr[] = mt_rand(1, 99); $start = microtime(true); $arr = array_flip($arr); // 值→鍵,重複值自動覆蓋 $arr = array_flip($arr); // 鍵→值,恢復原結構 $arr = array_values($arr); $end = microtime(true); echo 'double flip: ' . ($end - $start) * 1000 . ' ms, 內存: ' . round(memory_get_usage(true)/1024, 2) . ' KB'; // 結果:~13 ms, 768 KB
| 方法 | 耗時 | 內存 | 時間降低 | 內存降低 |
|---|---|---|---|---|
| array_unique() | 653 ms | 5120 KB | 基準 | 基準 |
| array_flip x2 | 13 ms | 768 KB | 98% | 85% |
array_flip,用 isset() 或 array_key_exists()array_flip() 雙重翻轉array_values() 重建索引array_flip 要求值為字符串或整數,且值唯一性由最後出現者決定array_search():返回鍵名,同樣 O(n)array_key_exists():檢查鍵存在,O(1),但比 isset() 慢(需檢查 null 值)isset():最快,但對 null 值返回 false