在PHP 中, array_filter()是一個非常常用的數組處理函數,主要用於過濾數組中的元素。這個函數可以接收一個可選的回調函數,用來定義哪些元素應該保留。如果沒有提供回調函數, array_filter()會自動去除數組中值為false 、 null 、 0 、空字符串和空數組等“假值”的元素。
那麼問題來了:在實際使用中, array_filter()使用默認行為與提供自定義回調函數之間,在性能上有什麼差異?哪種方式更高效?
本文將通過對比測試這兩種用法的執行時間,從性能的角度進行深入分析。
// 默認行為:移除數組中的“假值”
$result = array_filter($array);
// 使用回調函數:只保留大於 0 的值
$result = array_filter($array, function($value) {
return $value > 0;
});
我們構造一個包含大量元素的數組,並分別使用默認行為與自定義回調函數來過濾它們。
function testArrayFilterDefault($array) {
$start = microtime(true);
$result = array_filter($array);
return microtime(true) - $start;
}
function testArrayFilterCallback($array) {
$start = microtime(true);
$result = array_filter($array, function($value) {
return $value > 0;
});
return microtime(true) - $start;
}
// 構造測試數組,包含 100000 個元素
$testArray = [];
for ($i = 0; $i < 100000; $i++) {
$testArray[] = $i % 2 === 0 ? 0 : $i; // 一半是 0,一半是整數
}
// 執行測試
$timeDefault = testArrayFilterDefault($testArray);
$timeCallback = testArrayFilterCallback($testArray);
echo "默認行為执行时间:{$timeDefault} 秒\n";
echo "回調函數執行時間:{$timeCallback} 秒\n";
運行上面的腳本,你會發現默認行為在絕大多數情況下執行得更快。原因如下:
默認行為是C 語言層實現的內建邏輯,執行效率更高。
使用回調函數時,PHP 每次都需要調用用戶自定義的函數,函數調用開銷不容忽視,尤其是在大量數據時。
示例輸出(根據具體機器略有不同):
默認行為执行时间:0.012345 秒
回調函數執行時間:0.035678 秒
可以看到,默認行為大約快了兩到三倍。
雖然默認行為性能更優,但它有局限性——只能去除“假值”。如果你的過濾邏輯稍微複雜,比如保留特定範圍的數值、類型檢查等,依然需要回調函數。
例如:
// 保留奇數值
array_filter($array, function($v) {
return $v % 2 !== 0;
});
這顯然不能通過默認行為實現。
$userInput = [
'name' => 'Alice',
'email' => '',
'age' => 0,
'newsletter' => false,
];
$cleanedInput = array_filter($userInput); // 只保留非假值字段
// 輸出 ['name' => 'Alice']
在這個例子中,如果你希望移除所有未填寫的字段(包括false 、空字符串等),默認行為就非常合適。而如果你希望只保留非空字符串字段,則需要使用回調:
$cleanedInput = array_filter($userInput, function($value) {
return is_string($value) && trim($value) !== '';
});
使用方式 | 性能 | 靈活性 | 使用場景 |
---|---|---|---|
默認行為 | ? 高效 | ? 受限 | 去除假值 |
使用回調函數 | ? 稍慢 | ? 靈活 | 自定義過濾邏輯 |
建議:如果只是移除假值,使用默認行為即可;如果需要更複雜的邏輯,使用回調函數無可避免。