为了账号安全,请及时绑定邮箱和手机立即绑定

php 双层foreach 如何提升效率

php 双层foreach 如何提升效率

PHP
智慧大石 2019-03-14 09:34:11
两个数组都是近万条元素 切都是二维数组 请问如何优化提高效率 php版本 5.3 foreach ($arrayorser as $key => $value) { foreach ($search_order as $k => $v) { if ($value['order_id'] == $v['order_id']) { $arr[] = $value; } } }
查看完整描述

7 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

$search_order_ids = array_map(function ($o) {
    return $o['order_id'];
}, $search_order);

$arr = array_filter($arrayorser, function ($o) use ($search_order_ids) {
    return in_array($o['order_id'], $search_order_ids); 
});

我简单测了下, 时间比你的少. 你可以试试.

查看完整回答
反对 回复 2019-03-18
?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

给你分析一下:
假如两个数组都有1w条,那你两层foreach要循环1W*1W=1Y次

给你一个最简单的方法,只循环1w次就够了。

$search_order_id_arr=array_unique(array_column($search_order,'order_id'));
foreach ($arrayorser as $key => $value) {
    if(in_array($value['order_id'],$search_order_id_arr)){
        $arr[] = $value;
    }
}

去年的回答,看到有人点赞,我就再优化了一版,追求更高效率。2018-01-12

$search_order_id_arr=array_unique(array_column($search_order,'order_id'));
$arr=array_filter($arrayorser,function($value)use($search_order_id_arr){
    return in_array($value['order_id'],$search_order_id_arr);
});

不需要任何foreach,一切利用系统提供的函数来更高效的完成。

查看完整回答
反对 回复 2019-03-18
?
慕容3067478

TA贡献1773条经验 获得超3个赞

上面几个回答都只是将你的代码换了一种写法,没什么实际速度提升。

这个问题是将两个二维数组相同数据提取出来,这是一个纯时间复杂度的问题。计算一下时间复杂度,你的代码是1w * 1w,这是最笨的办法了,利用PHP数组的键值特性,稍微改造一下,就能达到1w * 2的效果,看代码:


// 中间数组
$_arr = [];

// 建立一个中间数据以 order_id 作为键
foreach ($search_order as $key => $value) {
    $_arr[$value['order_id']] = [];
}

// 遍历另一个数组,执行相关业务
foreach ($arrayorser as $key => $value) {
    if (isset($_arr[$value['order_id']])) {
        $_arr[$value['order_id']] = $value;
    }
}

到这里 $_arr 里面的数据就和你的一样了,以order_id为数组索引。如果想要使用自增数字作为数组索引:

$_mix = [];

// 遍历另一个数组,执行相关业务
foreach ($arrayorser as $key => $value) {
    if (isset($_arr[$value['order_id']])) {
        $_mix[] = $value;
    }
}
查看完整回答
反对 回复 2019-03-18
?
慕桂英546537

TA贡献1848条经验 获得超10个赞

@风兮清扬

  
        foreach ($arrayorser as $key=> $value){
            $ser[] = $value['order_id'];
        }
        foreach ($search_order as $k=>$v){
            $sers[] = $v['order_id'];
        }
        foreach ($ser as $key=> $item){
            if(in_array($item,$sers)){
                $arr[$key]['order_id'] = $item;
            }
        }

这是我写的很low,测试了你代码 你的在时间上相对平稳 8.4s 我的在 8.3~8.49s 之间 最后还是采用了你的

查看完整回答
反对 回复 2019-03-18
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

可以分批来处理这几万条数据吗?你的服务器内存一下子放那么多数据,foreach循环处理可能会报错,foreach的时候最好直接引用数组地址来操作,即加个&,不要再去拷贝一份数组了

查看完整回答
反对 回复 2019-03-18
?
慕森王

TA贡献1777条经验 获得超3个赞

先对两个数组进行order_id排序,再遍历会快一些

查看完整回答
反对 回复 2019-03-18
  • 7 回答
  • 0 关注
  • 970 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信