當前位置: 首頁> 最新文章列表> array_filter() 性能分析:回調vs 默認行為

array_filter() 性能分析:回調vs 默認行為

M66 2025-05-17

在PHP 中, array_filter()是一個非常常用的數組處理函數,主要用於過濾數組中的元素。這個函數可以接收一個可選的回調函數,用來定義哪些元素應該保留。如果沒有提供回調函數, array_filter()會自動去除數組中值為falsenull0 、空字符串和空數組等“假值”的元素。

那麼問題來了:在實際使用中, 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) !== '';
});

六、總結

使用方式性能靈活性使用場景
默認行為? 高效? 受限去除假值
使用回調函數? 稍慢? 靈活自定義過濾邏輯

建議:如果只是移除假值,使用默認行為即可;如果需要更複雜的邏輯,使用回調函數無可避免。