PHP的数组中提高元素查找与元素去重的效率的技巧解析


Posted in PHP onMarch 03, 2016

提高查找数组元素的效率
1.php in_array方法说明

php查找数组元素是否存在,一般会使用in_array方法。

bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )

参数说明:
needle
待搜索的值,如果needle是字符串,比较是区分大小写的。

haystack
用来比较的数组

strict
如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会检查 needle 的类型是否和 haystack 中的相同

返回值
如果找到 needle 则返回 TRUE,否则返回 FALSE。

2.in_array查找元素效率

当比较的数组haystack较大时,in_array效率会很低

例子:使用in_array对有10万个元素的数组进行1000次比较

<?php
$arr = array();

// 创建10万个元素的数组
for($i=0; $i<100000; $i++){
  $arr[] = $i;
}

// 记录开始时间
$starttime = getMicrotime();

// 随机创建1000个数字使用in_array比较
for($j=0; $j<1000; $j++){
  $str = mt_rand(1,99999);
  in_array($str, $arr);
}

// 记录结束时间
$endtime = getMicrotime();

echo 'run time:'.(float)(($endtime-$starttime)*1000).'ms<br>';

/**
 * 获取microtime
 * @return float
 */
function getMicrotime(){
  list($usec, $sec) = explode(' ', microtime());
  return (float)$usec + (float)$sec;
}
?>
run time:2003.6449432373ms

使用in_array判断元素是否存在,在10万个元素的数组中比较1000次,运行时间需要约2秒

3.提高查找元素效率方法

我们可以先使用array_flip进行键值互换,然后使用isset方法来判断元素是否存在,这样可以提高效率。

例子:使用array_flip先进行键值互换,再使用isset方法判断,在10万个元素的数组中比较1000次

<?php
$arr = array();

// 创建10万个元素的数组
for($i=0; $i<100000; $i++){
  $arr[] = $i;
}

// 键值互换
$arr = array_flip($arr);

// 记录开始时间
$starttime = getMicrotime();

// 随机创建1000个数字使用isset比较
for($j=0; $j<1000; $j++){
  $str = mt_rand(1,99999);
  isset($arr[$str]);
}

// 记录结束时间
$endtime = getMicrotime();

echo 'run time:'.(float)(($endtime-$starttime)*1000).'ms<br>';

/**
 * 获取microtime
 * @return float
 */
function getMicrotime(){
  list($usec, $sec) = explode(' ', microtime());
  return (float)$usec + (float)$sec;
}
?>
run time:1.2781620025635ms

使用array_flip与isset判断元素是否存在,在10万个元素的数组中比较1000次,运行时间需要约1.2毫秒

因此,对于大数组进行比较,使用array_flip与isset方法会比in_array效率高很多。


快速去重
1.使用array_unique方法进行去重

对数组元素进行去重,我们一般会使用array_unique方法,使用这个方法可以把数组中的元素去重。

<?php
$arr = array(1,1,2,3,3,3,4,4,5,6,6,7,8,8,9,9,9);
$arr = array_unique($arr);
$arr = array_values($arr);
print_r($arr);
?>

输出:

Array
(
  [0] => 1
  [1] => 2
  [2] => 3
  [3] => 4
  [4] => 5
  [5] => 6
  [6] => 7
  [7] => 8
  [8] => 9
)

去重后,键值会不按顺序,可以使用array_values把键值重新排序。

2.使用array_unique方法去重效率

<?php
$arr = array();

// 创建100000个随机元素的数组
for($i=0; $i<100000; $i++){
  $arr[] = mt_rand(1,99);
}

// 记录开始时间
$starttime = getMicrotime();

// 去重
$arr = array_unique($arr);

// 记录结束时间
$endtime = getMicrotime();

$arr = array_values($arr);

echo 'unique count:'.count($arr).'<br>';
echo 'run time:'.(float)(($endtime-$starttime)*1000).'ms<br>';
echo 'use memory:'.getUseMemory();

/**
 * 获取使用内存
 * @return float
 */
function getUseMemory(){
  $use_memory = round(memory_get_usage(true)/1024,2).'kb';
  return $use_memory;
}

/**
 * 获取microtime
 * @return float
 */
function getMicrotime(){
  list($usec, $sec) = explode(' ', microtime());
  return (float)$usec + (float)$sec;
}
?>
unique count:99 
run time:653.39303016663ms 
use memory:5120kb

使用array_unique方法去重,运行时间需要约650ms,内存占用约5m


3.更快的数组去重方法

php有一个键值互换的方法array_flip,我们可以使用这个方法去重,因为键值互换,原来重复的值会变为相同的键。
然后再进行一次键值互换,把键和值换回来则可以完成去重。

<?php
$arr = array();

// 创建100000个随机元素的数组
for($i=0; $i<100000; $i++){
  $arr[] = mt_rand(1,99);
}

// 记录开始时间
$starttime = getMicrotime();

// 使用键值互换去重
$arr = array_flip($arr);
$arr = array_flip($arr);

// 记录结束时间
$endtime = getMicrotime();

$arr = array_values($arr);

echo 'unique count:'.count($arr).'<br>';
echo 'run time:'.(float)(($endtime-$starttime)*1000).'ms<br>';
echo 'use memory:'.getUseMemory();

/**
 * 获取使用内存
 * @return float
 */
function getUseMemory(){
  $use_memory = round(memory_get_usage(true)/1024,2).'kb';
  return $use_memory;
}

/**
 * 获取microtime
 * @return float
 */
function getMicrotime(){
  list($usec, $sec) = explode(' ', microtime());
  return (float)$usec + (float)$sec;
}
?>
unique count:99 
run time:12.840032577515ms 
use memory:768kb

使用array_flip方法去重,运行时间需要约18ms,内存占用约2m

因此使用array_flip方法去重比使用array_unique方法运行时间减少98%,内存占用减少4/5;

PHP 相关文章推荐
来自phpguru得Php Cache类源码
Apr 15 PHP
第四章 php数学运算
Dec 30 PHP
PHP用身份证号获取星座和生肖的方法
Nov 07 PHP
PHP加密扩展库Mcrypt安装和实例
Nov 10 PHP
PHP实现把文本中的URL转换为链接的auolink()函数分享
Jul 29 PHP
从零开始学YII2框架(一)通过Composer安装Yii2框架
Aug 20 PHP
PHP实现阳历到农历转换的类实例
Mar 07 PHP
php转换颜色为其反色的方法
Apr 27 PHP
php常用字符串String函数实例总结【转换,替换,计算,截取,加密】
Dec 07 PHP
PHP类与对象后期静态绑定操作实例详解
Dec 20 PHP
浅谈Laravel模板实体转义带来的坑
Oct 22 PHP
ThinkPHP 5 AJAX跨域请求头设置实现过程解析
Oct 28 PHP
CodeIgniter针对数据库的连接、配置及使用方法
Mar 03 #PHP
CodeIgniter表单验证方法实例详解
Mar 03 #PHP
PHP6新特性分析
Mar 03 #PHP
php轻松实现文件上传功能
Mar 03 #PHP
php编程每天必学之验证码
Mar 03 #PHP
简单介绍PHP非阻塞模式
Mar 03 #PHP
浅析php设计模式之数据对象映射模式
Mar 03 #PHP
You might like
颠覆常识!无色透明的咖啡诞生了(中日双语)
2021/03/03 咖啡文化
用mysql触发器自动更新memcache的实现代码
2009/10/11 PHP
PHP实现批量检测网站是否能够正常打开的方法
2016/08/23 PHP
PHP实现登录注册之BootStrap表单功能
2017/09/03 PHP
MooTools 1.2中的Drag.Move来实现拖放
2009/09/15 Javascript
jQuery中绑定事件的命名空间详解
2011/04/05 Javascript
设为首页加入收藏兼容360/火狐/谷歌/IE等主流浏览器的代码
2013/03/26 Javascript
使用js修改客户端注册表的方法
2013/08/09 Javascript
js兼容的placeholder属性详解
2013/08/18 Javascript
replace()方法查找字符使用示例
2013/10/28 Javascript
jquery 多个radio的click事件实例
2016/12/03 Javascript
JS表单提交验证、input(type=number) 去三角 刷新验证码
2017/06/21 Javascript
新手快速上手webpack4打包工具的使用详解
2019/01/28 Javascript
浅谈JS和jQuery的区别
2019/03/27 jQuery
localstorage实现带过期时间的缓存功能
2019/06/28 Javascript
Vue.js自定义指令学习使用详解
2019/10/19 Javascript
vue动画—通过钩子函数实现半场动画操作
2020/08/09 Javascript
浅谈Vue static 静态资源路径 和 style问题
2020/11/07 Javascript
python处理json数据中的中文
2014/03/06 Python
利用python实现命令行有道词典的方法示例
2017/01/31 Python
Python将图片转换为字符画的方法
2020/06/16 Python
Python----数据预处理代码实例
2019/03/20 Python
Python中的list与tuple集合区别解析
2019/10/12 Python
python 6.7 编写printTable()函数表格打印(完整代码)
2020/03/25 Python
Python实现定时监测网站运行状态的示例代码
2020/09/30 Python
波兰快递服务:Globkurier.pl
2019/11/08 全球购物
审计主管岗位职责
2014/01/31 职场文书
万年牢教学反思
2014/02/15 职场文书
优秀团员自我评价范文
2014/04/23 职场文书
我心目中的好老师活动方案
2014/08/19 职场文书
运动会表扬稿范文
2015/05/05 职场文书
义卖募捐活动总结
2015/05/09 职场文书
英语专业毕业论文答辩开场白
2015/05/27 职场文书
2016年三八节红领巾广播稿
2015/12/17 职场文书
解决mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO/YES)
2021/06/26 MySQL
Vue elementUI表单嵌套表格并对每行进行校验详解
2022/02/18 Vue.js