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简介
Oct 09 PHP
PHP中全面阻止SQL注入式攻击分析小结
Jan 30 PHP
php上传apk后自动提取apk包信息的使用(示例下载)
Apr 26 PHP
PHP以指定字段为索引返回数据库所取的数据数组
Jun 30 PHP
那些年我们错过的魔术方法(Magic Methods)
Jan 14 PHP
php判断访问IP的方法
Jun 19 PHP
php实现Mysql简易操作类
Oct 11 PHP
PHP MSSQL 分页实例
Apr 13 PHP
解决php-fpm.service not found问题的办法
Jun 06 PHP
深入理解Yii2.0乐观锁与悲观锁的原理与使用
Jul 26 PHP
PHP基于自定义函数生成笛卡尔积的方法示例
Sep 30 PHP
解决laravel资源加载路径设置的问题
Oct 14 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+mysql实现无限级分类 | 树型显示分类关系
2006/11/19 PHP
用PHP ob_start()控制浏览器cache、生成html实现代码
2010/02/16 PHP
PHP+ajax 无刷新删除数据
2010/02/20 PHP
php in_array 函数使用说明与in_array需要注意的地方说明
2010/04/13 PHP
PHP+MYSQL会员系统的登陆即权限判断实现代码
2011/09/23 PHP
php curl选项列表(超详细)
2013/07/01 PHP
php的webservice的wsdl的XML无法显示问题的解决方法
2014/03/11 PHP
PHP的Json中文处理解决方案
2016/09/29 PHP
浅谈JavaScript中面向对象技术的模拟
2006/09/25 Javascript
一个加载js文件的小脚本
2007/06/28 Javascript
[Web]防止用户复制页面内容和另存页面的方法
2009/02/06 Javascript
js实现遮罩层弹出框的方法
2015/01/15 Javascript
JavaScript原生xmlHttp与jquery的ajax方法json数据格式实例
2015/12/04 Javascript
JavaScript实现Base64编码转换
2016/04/23 Javascript
如何制作幻灯片(代码分享)
2017/01/06 Javascript
深入理解Javascript中的作用域链和闭包
2017/04/25 Javascript
浅析JS中回调函数及用法
2018/07/25 Javascript
如何获取vue单文件自身源码路径
2019/05/06 Javascript
vue cli安装使用less的教程详解
2019/07/12 Javascript
[04:01]2014DOTA2国际邀请赛 TITAN告别Ohaiyo期望明年再战
2014/07/15 DOTA
[04:19]DOTA2亚洲邀请赛 现场花絮
2015/03/11 DOTA
Python导入oracle数据的方法
2015/07/10 Python
开源Web应用框架Django图文教程
2017/03/09 Python
django实现登录时候输入密码错误5次锁定用户十分钟
2017/11/05 Python
python爬取亚马逊书籍信息代码分享
2017/12/09 Python
Python文件操作基本流程代码实例
2017/12/11 Python
使用python serial 获取所有的串口名称的实例
2019/07/02 Python
python函数不定长参数使用方法解析
2019/12/14 Python
Keras官方中文文档:性能评估Metrices详解
2020/06/15 Python
python正则表达式 匹配反斜杠的操作方法
2020/08/07 Python
美国在线面料商店:Fashion Fabrics Club
2020/01/31 全球购物
《藏戏》教学反思
2014/02/11 职场文书
党的群众路线教育实践活动个人对照检查材料
2014/09/22 职场文书
搞笑婚前保证书
2015/02/28 职场文书
2016年国培心得体会及反思
2016/01/13 职场文书
Java使用Unsafe类的示例详解
2021/09/25 Java/Android