在PHP开发过程中,数组是非常重要的数据结构,往往有一个操作就是对数组进行过滤,修改,以下是对数组元素进行过滤的几个方法进行分析。
数据源是长度为4592的数组,占用内存8.9MB,方法重复执行5000次。
结论:无论是对数组进行过滤,修改,使用引用的方式是最优的,主要原因在于内存操作次数少。array_filter和array_walk需要调用一次函数,所耗的时间会更长
过滤数组 | 执行时间 | 修改数组的值 | 执行时间 |
使用复制的形式 | 18s | 使用复制的形式 | 118s |
使用引用 | 16s | 使用引用 | 12s |
使用array_filter | 62s | 使用array_walk | 117s |
方式一:使用复制的形式
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函数有非常多的内存操作。