注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

牧笔临风

己有能,勿自私!

 
 
 

日志

 
 
 
 

PHP数组交集的优化  

2012-02-21 21:33:09|  分类: php |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

假设我们正在运营一个手机相关的网站,用户可以通过指定若干参数(如操作系统,屏幕分辨率,摄像头像素等等)来筛选自己想要的手机。不过由于手机的参数多,且不同的手机其参数差异大,所以参数表结构通常是纵表(一个参数是一行),而不是横表(一个参数是一列),此时使用若干参数来取结果,通常就是把每个单独参数来取结果,再一起取交集。

假定每个参数会包含一千个左右的结果,以此为前提来模拟生成一些数据:

以下是代码片段:
<?php 

$rand = function() { 
    $result = array(); 

    for ($i = 0; $i < 1000; null) { 
        $value = mt_rand(1, 10000); 

        if (!isset($result[$value])) { 
            $result[$value] = null; 
            $i++; 
        } 
    } 

    return array_keys($result); 
}; 

$param_a = $rand(); 
$param_b = $rand(); 

?>
注:留意数据量的大小,以几百到几万为宜。

先来看看通过PHP内置方法array_intersect实现的性能:

以下是代码片段:
<?php 

$time = microtime(true); 

$result = array_intersect($param_a, $param_b); 

$time = microtime(true) - $time; 

echo "array_intersect: {$time}\n"; 

?>
再来看看通过自定义方法intersect实现的性能:

以下是代码片段:
<?php 

function intersect() { 
    if (!func_num_args()) { 
        die('param error'); 
    } 

    $arr  = func_get_args();
    foreach ($arr as $k => $arg) { 
        if (!is_array($arg)) { 
            die('param error'); 
        }else{
            $arr[$k] = array_unique($arg);
        }
    } 
    $result = array(); 
    $data = array_count_values(call_user_func_array('array_merge', $arr)); 
    foreach ($data as $value => $count) { 
        if ($count > 1) { 
            $result[] = $value; 
        } 
    } 
    return $result; 


$time = microtime(true); 

$result = intersect($param_a, $param_b); 

$time = microtime(true) - $time; 

echo "intersect: {$time}\n"; 

?>
注:如果数组元素的数量很大的话,array_merge的时候可能会溢出。

直觉上,我们肯定会认为内置函数快于自定义函数,但本例中结果恰恰相反:

array_intersect: 0.023918151855469
intersect: 0.0026049613952637
这是因为array_intersect和intersect的功能并不完全等价,看下面的例子:

以下是代码片段:
$param_a = array(1, 2, 2); 
$param_b = array(1, 2, 3); 

var_dump( 
    array_intersect($param_a, $param_b), 
    intersect($param_a, $param_b) 
);
array_intersect: 1, 2, 2
intersect: 1, 2
也就是说,如果在第一个数组参数中有重复元素的话,则array_intersect会返回所有满足条件的重复元素,而不是仅仅返回一个,有兴趣的读者可以变换一下参数顺序再看结果。

实际使用中,很多情况下我们都能保证数组参数没有重复元素,交集其实就是求合并数组中元素数量大于一的集合,此时在速度上array_intersect就显得鸡肋了。
  评论这张
 
阅读(212)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017