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 相关文章推荐
PHP邮件专题
Oct 09 PHP
珊瑚虫IP库浅析
Feb 15 PHP
让PHP开发者事半功倍的十大技巧小结
Apr 20 PHP
Memcached常用命令以及使用说明详解
Jun 27 PHP
使用PHP会话(Session)实现用户登陆功能
Jun 29 PHP
WordPress自定义时间显示格式
Mar 27 PHP
thinkphp框架实现数据添加和显示功能
Jun 29 PHP
PHP控制反转(IOC)和依赖注入(DI)
Mar 13 PHP
ThinkPHP框架实现数据增删改
May 07 PHP
PHP mysqli事务操作常用方法分析
Jul 22 PHP
PHP使用POP3读取邮箱接收邮件的示例代码
Jul 08 PHP
php中数组最简单的使用方法
Dec 27 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
WIN98下Apache1.3.14+PHP4.0.4的安装
2006/10/09 PHP
php实现过滤字符串中的中文和数字实例
2015/07/29 PHP
PHP观察者模式原理与简单实现方法示例
2017/08/25 PHP
onpropertypchange
2006/07/01 Javascript
javascript一点特殊用法
2008/05/28 Javascript
在Linux上用forever实现Node.js项目自启动
2014/07/09 Javascript
IE浏览器IFrame对象内存不释放问题解决方法
2014/08/22 Javascript
详解JavaScript编程中的数组结构
2015/10/24 Javascript
javascript的几种继承方法介绍
2016/03/22 Javascript
Javascript学习之谈谈JS的全局变量跟局部变量(推荐)
2016/08/28 Javascript
JS实现屏蔽网页右键复制及ctrl+c复制的方法【2种方法】
2016/09/04 Javascript
jQuery leonaScroll 1.1 自定义滚动条插件(推荐)
2016/09/17 Javascript
vue制作加载更多功能的正确打开方式
2016/10/12 Javascript
基于BootstrapValidator的Form表单验证(24)
2016/12/12 Javascript
Angular.JS中select下拉框设置value的方法
2017/06/20 Javascript
基于 Bootstrap Datetimepicker 联动
2017/08/03 Javascript
Bootstrap table使用方法记录
2017/08/23 Javascript
如何在vue项目中嵌入jsp页面的方法(2种)
2020/02/06 Javascript
openlayers实现图标拖动获取坐标
2020/09/25 Javascript
js加减乘除精确运算方法实例代码
2021/01/17 Javascript
Python实现合并字典的方法
2015/07/07 Python
Python中断言Assertion的一些改进方案
2016/10/27 Python
Python网络爬虫出现乱码问题的解决方法
2017/01/05 Python
Python基于回溯法子集树模板解决找零问题示例
2017/09/11 Python
python 批量解压压缩文件的实例代码
2019/06/27 Python
python tkinter图形界面代码统计工具
2019/09/18 Python
Numpy之reshape()使用详解
2019/12/26 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
python无序链表删除重复项的方法
2020/01/17 Python
Python用input输入列表的实例代码
2020/02/07 Python
Hotels.com台湾:饭店订房网
2017/09/06 全球购物
英语文学专业学生的自我评价
2013/10/31 职场文书
英文版销售经理个人求职信
2013/11/20 职场文书
幼儿教育感言
2014/02/05 职场文书
公司员工宿舍管理制度
2015/08/03 职场文书
Spring Security动态权限的实现方法详解
2022/06/16 Java/Android