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 相关文章推荐
如何分别全角和半角以避免乱码
Oct 09 PHP
来自PHP.NET的入门教程
Oct 09 PHP
腾讯QQ php程序员面试题目整理
Jun 08 PHP
PHP header函数分析详解
Aug 06 PHP
PHP实现时间轴函数代码
Oct 08 PHP
Pain 全世界最小最简单的PHP模板引擎 (普通版)
Oct 23 PHP
解析file_get_contents模仿浏览器头(user_agent)获取数据
Jun 27 PHP
php防止站外远程提交表单的方法
Oct 20 PHP
thinkPHP学习笔记之安装配置篇
Mar 05 PHP
PHP 用session与gd库实现简单验证码生成与验证的类方法
Nov 15 PHP
实例讲解YII2中多表关联的使用方法
Jul 21 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
Aug 30 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
一个取得文件扩展名的函数
2006/10/09 PHP
php 无法载入mysql扩展
2010/03/12 PHP
解析phpstorm + xdebug 远程断点调试
2013/06/20 PHP
更改localhost为其他名字的方法
2014/02/10 PHP
PHP实现简单的新闻发布系统实例
2015/07/28 PHP
如何正确配置Nginx + PHP
2016/07/15 PHP
添加JavaScript重载函数的辅助方法2
2010/07/04 Javascript
js与jquery中获取当前鼠标的x、y坐标位置的代码
2011/05/23 Javascript
jquery+css+ul模拟列表菜单具体实现思路
2013/04/15 Javascript
从零学JSON之JSON数据结构
2014/05/19 Javascript
JQuery中属性过滤选择器用法实例分析
2015/05/18 Javascript
JavaScript实现的Tween算法及缓冲特效实例代码
2015/11/03 Javascript
js省市联动效果完整实例代码
2015/12/09 Javascript
jQuery Ajax 全局调用封装实例代码详解
2016/06/02 Javascript
Javascript 5种方法实现过滤删除前后所有空格
2016/06/22 Javascript
AngularJS 整理一些优化的小技巧
2016/08/18 Javascript
node.js文件上传处理示例
2016/10/27 Javascript
Ajax实现不刷新取最新商品
2017/03/01 Javascript
微信小程序实现多选框全选与取消全选功能示例
2019/05/14 Javascript
JS立即执行的匿名函数用法分析
2019/11/04 Javascript
vue路由传参的基本实现方式小结【三种方式】
2020/02/05 Javascript
如何在postman测试用例中实现断言过程解析
2020/07/09 Javascript
django 2.0更新的10条注意事项总结
2018/01/05 Python
tensorflow构建BP神经网络的方法
2018/03/12 Python
TensorFlow内存管理bfc算法实例
2020/02/03 Python
美国顶级水上运动专业店:Marine Products
2018/04/15 全球购物
iKRIX意大利网上商店:男女豪华服装和配件
2019/10/09 全球购物
医学专业五年以上个人求职信
2013/12/03 职场文书
水利学院求职自荐书
2014/02/01 职场文书
五一促销活动总结
2014/07/01 职场文书
思想政治表现评语
2015/01/04 职场文书
公司会议开幕词
2015/01/29 职场文书
2015年保险公司工作总结
2015/04/24 职场文书
大国崛起日本观后感
2015/06/02 职场文书
golang生成vcf通讯录格式文件详情
2022/03/25 Golang
html用代码制作虚线框怎么做? dw制作虚线圆圈的技巧
2022/12/24 HTML / CSS