php 双层foreach 如何提升效率

两个数组都是近万条元素 切都是二维数组 请问如何优化提高效率 php版本 5.3

 foreach ($arrayorser as $key => $value) {
            foreach ($search_order as $k => $v) {
                if ($value['order_id'] == $v['order_id']) {
                    $arr[] = $value;
                }
            }
        }
阅读 10k
7 个回答
$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); 
});

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

给你分析一下:
假如两个数组都有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,一切利用系统提供的函数来更高效的完成。

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

这个问题是将两个二维数组相同数据提取出来,这是一个纯时间复杂度的问题。计算一下时间复杂度,你的代码是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;
    }
}
foreach ($search_order as $value){
    $search_order_new[$value['order_id']] = $value;
}
foreach ($arrayorser as $value){
    $arrayorser_new[$value['order_id']] = $value;
}
$result = array_intersect_key($arrayorser_new, $search_order_new);

试试这个,简单点好,别搞复杂的

@风兮清扬

  
        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 之间 最后还是采用了你的

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

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

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏