PHP大陣列過濾元素、修改元素效能分析
在PHP開發過程中,陣列是非常重要的資料結構,往往有一個操作就是對陣列進行過濾,修改,以下是對陣列元素進行過濾的幾個方法進行分析。
資料來源是長度為4592的陣列,佔用記憶體8.9MB,方法重複執行5000次。
結論:無論是對陣列進行過濾,修改,使用引用的方式是最優的,主要原因在於記憶體操作次數少。array_filter和array_walk需要呼叫一次函式,所耗的時間會更長
過濾陣列 | 執行時間 | 修改陣列的值 | 執行時間 |
使用複製的形式 | 18s | 使用複製的形式 | 118s |
使用引用 | 16s | 使用引用 | 12s |
使用array_filter | 62s | 使用array_walk | 117s |
一、測試過濾陣列,過濾條件是過濾元素中sequence欄位為奇數的資料。
方式一:使用複製的形式
for ($i = 1; $i <= 5000; $i++) {
$result = formatter1($data);
}
function formatter1($data)
{
$result = [];
foreach ($data as $d) {
if ($d['sequence'] % 2 == 0) {
$result[] = $d;
}
}
return $result;
}
xprof測試結果
函式耗時:18s,formatter1函式中有非常多的記憶體操作
方式二:刪除原陣列元素
for ($i = 1; $i <= 5000; $i++) {
formatter2($opt);
}
function formatter2($data)
{
foreach ($data as $k => $v) {
if ($v['sequence'] % 2 == 1) {
unset($data[$k]);
}
}
$data = array_values($data);
}
函式耗時:16s,同時佔用記憶體也是非常低。
方式三:使用array_filter函式+閉包
function formatter3($data)
{
return array_values(array_filter($data, function($val){
return $val['sequence'] % 2 == 0;
}));
}
函式耗時:62s,非常差,而且閉包函式佔用了非常多的記憶體(堆疊呼叫)。
二、新增和修改元素的內容
這裡我們為每個元素新增一個new='add',以及修改原有sequence+=100,通過2種方法進行對比,一個是使用複製的形式,另一個是引用修改的形式。
方式一:使用複製的形式
function modify_method1($data)
{
$result = [];
foreach ($data as $d) {
$d['new'] = 'add';
$d['sequence'] += 100;
$result[] = $d;
}
return $result;
}
從結果看,執行時間為118s,modify_method1函式中有非常多的記憶體操作,峰值佔用記憶體在13MB。
方式二:使用引用修改的形式
function modify_method2(&$data, $i)
{
foreach ($data as &$d) {
$d['new'] = $i;
$d['sequence'] += 100;
}
}
從結果看,執行時間為12s,modify_method2函式基本上不新增記憶體操作。
方式三:使用array_walk
function modify_method3($data)
{
array_walk($data, function(&$val){
$val['new'] = 'add';
$val['sequence'] += 100;
});
return $data;
}
耗時,117s,modify_method3函式有非常多的記憶體操作。