PHP数组交集的优化代码分析


Posted in PHP onMarch 06, 2011

不过由于手机的参数多,且不同的手机其参数差异大,所以参数表结构通常是纵表(一个参数是一行),而不是横表(一个参数是一列),此时使用若干参数来取结果,通常就是把每个单独参数来取结果,再一起取交集。
假定每个参数会包含一千个左右的唯一结果(id int),以此为前提来模拟生成一些数据:

<?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() < 2) { 
trigger_error('param error', E_USER_ERROR); 
} 
$args = func_get_args(); 
foreach ($args AS $arg) { 
if (!is_array($arg)) { 
trigger_error('param error', E_USER_ERROR); 
} 
} 
$intersect = function($a, $b) { 
$result = array(); 
$length_a = count($a); 
$length_b = count($b); 
for ($i = 0, $j = 0; $i < $length_a && $j < $length_b; null) { 
if($a[$i] < $b[$j]) { 
$i++; 
} else if($a[$i] > $b[$j]) { 
$j++; 
} else { 
$result[] = $a[$i]; 
$i++; 
$j++; 
} 
} 
return $result; 
}; 
$result = array_shift($args); 
sort($result); 
foreach ($args as $arg) { 
sort($arg); 
$result = $intersect($result, $arg); 
} 
return $result; 
} 
$time = microtime(true); 
$result = intersect($param_a, $param_b); 
$time = microtime(true) - $time; 
echo "intersect: {$time}\n"; 
?>

直觉上,我们肯定会认为内置函数快于自定义函数,但本例中结果恰恰相反:
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会返回所有满足条件的重复元素,而不是仅仅返回一个,有兴趣的读者可以变换一下参数顺序再看结果。
再唠叨一下,最初我写intersect方法时,大概写成下面这个样子:
<?php 
function intersect() { 
if (func_num_args() < 2) { 
trigger_error('param error', E_USER_ERROR); 
} 
$args = func_get_args(); 
foreach ($args AS $arg) { 
if (!is_array($arg)) { 
trigger_error('param error', E_USER_ERROR); 
} 
} 
$result = array(); 
$data = array_count_values( 
call_user_func_array('array_merge', $args) 
); 
foreach ($data AS $value => $count) { 
if ($count > 1) { 
$result[] = $value; 
} 
} 
return $result; 
} 
?>

代码更简洁,不过有一个弊端,因为使用了array_merge,所以当数组中元素非常多的时候,占用的内存会比较大,反之如果数组中元素不是非常多,那么此方法也是可行的。(来源:火丁笔记)
PHP 相关文章推荐
PHP分页显示制作详细讲解
Dec 05 PHP
php 无限分类的树类代码
Dec 03 PHP
JS中encodeURIComponent函数用php解码的代码
Mar 01 PHP
php比较多维数组中值的大小排序实现代码
Sep 08 PHP
PHP类与对象中的private访问控制的疑问
Nov 01 PHP
解决FastCGI 进程超过了配置的活动超时时限的问题
Jul 03 PHP
php setcookie函数的参数说明及其用法
Apr 20 PHP
php使用PDO方法详解
Dec 27 PHP
Linux系统下php获得系统分区信息的方法
Mar 30 PHP
Yii2――使用数据库操作汇总(增删查改、事务)
Dec 19 PHP
PHP中Laravel 关联查询返回错误id的解决方法
Apr 01 PHP
PHP fopen中文文件名乱码问题解决方案
Oct 28 PHP
php下安装配置fckeditor编辑器的方法
Mar 02 #PHP
PHP如何抛出异常处理错误
Mar 02 #PHP
php中实现记住密码自动登录的代码
Mar 02 #PHP
防止用户利用PHP代码DOS造成用光网络带宽
Mar 01 #PHP
php Smarty 字符比较代码
Feb 27 #PHP
php下批量挂马和批量清马代码
Feb 27 #PHP
php SQL Injection with MySQL
Feb 27 #PHP
You might like
PHP 编程安全性小结
2010/01/08 PHP
PHP5中使用DOM控制XML实现代码
2010/05/07 PHP
php通过文件头检测文件类型通用代码类(zip,rar等)
2010/10/19 PHP
php实现点击可刷新验证码
2015/11/07 PHP
php脚本守护进程原理与实现方法详解
2017/07/20 PHP
PHP使用mongoclient简单操作mongodb数据库示例
2019/02/08 PHP
JavaScript confirm选择判断
2008/10/18 Javascript
jQuery 数据缓存data(name, value)详解及实现
2010/01/04 Javascript
javascript模版引擎-tmpl的bug修复与性能优化分析
2011/10/23 Javascript
非主流的textarea自增长实现js代码
2011/12/20 Javascript
火狐textarea输入法的bug的触发及解决
2013/07/24 Javascript
js获取url中的参数且参数为中文时通过js解码
2014/03/19 Javascript
解决node-webkit 不支持html5播放mp4视频的方法
2015/03/11 Javascript
深入探究使JavaScript动画流畅的一些方法
2015/06/30 Javascript
JavaScript中匿名函数的用法及优缺点详解
2016/06/01 Javascript
微信端开发--登录小程序步骤
2017/01/11 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
详解vue 模拟后台数据(加载本地json文件)调试
2017/08/25 Javascript
vue操作下拉选择器获取选择的数据的id方法
2018/08/24 Javascript
vue 点击展开显示更多(点击收起部分隐藏)
2019/04/09 Javascript
python中requests爬去网页内容出现乱码问题解决方法介绍
2017/10/25 Python
浅谈Python处理PDF的方法
2017/11/10 Python
Python3 jupyter notebook 服务器搭建过程
2018/11/30 Python
VScode连接远程服务器上的jupyter notebook的实现
2020/04/23 Python
Python3自定义json逐层解析器代码
2020/05/11 Python
python+excel接口自动化获取token并作为请求参数进行传参操作
2020/11/10 Python
python UDF 实现对csv批量md5加密操作
2021/01/01 Python
Quiksilver荷兰官方网站:冲浪和滑雪板
2019/11/16 全球购物
学前教育专业毕业生自荐信
2013/10/03 职场文书
计算机工程学院个人求职信
2013/10/05 职场文书
师范生自荐信
2013/10/27 职场文书
就业推荐表自我鉴定
2013/10/29 职场文书
淘宝店铺营销方案
2014/02/13 职场文书
《得道多助,失道寡助》教学反思
2014/04/19 职场文书
2014年店长工作总结
2014/11/17 职场文书
Android Canvas绘制文字横纵向对齐
2022/06/05 Java/Android