PHP 的「關聯數組」底層實現是 **有序哈希表 (Hash Table)**,這賦予了它 **O(1) 平均時間複雜度的鍵值查找** 能力。善用此特性,能將雙層循環 O(M×N) 的去重問題優化為 O(M+N)。本文深度解析原理、實戰對比、最佳實踐。
<?php
function filterUsersNested(array $users, array $blacklist): array {
foreach ($users as $key => $name) {
foreach ($blacklist as $blackName) {
if ($name === $blackName) {
unset($users[$key]); // 內層循環執行 M×N 次!
break;
}
}
}
return $users;
}
// 10,000 × 2,000 = 20,000,000 次比較
// 億級數據將不可接受
?>
<?php
function filterUsersHash(array $users, array $blacklist): array {
// 1. 構建黑名單哈希表:鍵=用戶名,值=true (佔用極小內存)
$blackHash = array_flip($blacklist); // O(N)
// 或手動: foreach ($blacklist as $name) $blackHash[$name] = true;
// 2. 遍歷用戶列表,O(1) 查找
foreach ($users as $key => $name) {
if (isset($blackHash[$name])) { // 平均 O(1)
unset($users[$key]);
}
}
return $users;
}
// 10,000 + 2,000 = 12,000 次操作
// 性能提升 ~1600 倍!
?>
| 函數 | 用途 | 時間複雜度 | 備註 |
|---|---|---|---|
isset($arr[$key]) | 檢查鍵是否存在 (不為 null) | O(1) | 最快,推薦去重/存在性檢查 |
array_key_exists($key, $arr) | 檢查鍵是否存在 (含 null 值) | O(1) | 稍慢,需區分 null 值時用 |
in_array($val, $arr) | 檢查值是否存在 | O(N) | 遍歷值,**避免大數組用** |
array_flip($arr) | 鍵值交換 | O(N) | 快速構建查找表 |
array_intersect_key() | 按鍵取交集 | O(N) | 高級去重/過濾 |
<?php
function filterMassiveUsers(string $userFile, string $blackFile, string $outputFile): void {
// 1. 載入黑名單到內存 (假設黑名單較小,如 100萬)
$blackHash = [];
$fp = fopen($blackFile, 'r');
while (($line = fgets($fp)) !== false) {
$blackHash[trim($line)] = true;
}
fclose($fp);
echo "黑名單載入: " . count($blackHash) . " 條\n";
// 2. 分塊讀取用戶文件,流式過濾寫入結果
$fpIn = fopen($userFile, 'r');
$fpOut = fopen($outputFile, 'w');
$processed = $removed = 0;
while (($line = fgets($fpIn)) !== false) {
$name = trim($line);
if (!isset($blackHash[$name])) {
fwrite($fpOut, $name . "\n");
} else {
$removed++;
}
$processed++;
if ($processed % 100000 === 0) {
echo "已處理: $processed, 移除: $removed\n";
}
}
fclose($fpIn);
fclose($fpOut);
echo "完成! 總計: $processed, 移除: $removed, 保留: " . ($processed - $removed) . "\n";
}
// 內存佔用恆定 (僅黑名單哈希表),支持任意大小用戶文件
?>
PHP 關聯數組 = 高性能有序哈希表。**理解其 O(1) 查找特性,是編寫高性能 PHP 代碼的分水嶺**。將 O(M×N) 雙層循環重構為 O(M+N) 哈希查找,不僅是算法優化,更是對語言底層特性的正確運用。面對億級數據,**流式處理 + 內存哈希表** 是通用解法。