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 相关文章推荐
隐藏X-Space个人空间下方版权方法隐藏X-Space个人空间标题隐藏X-Space个人空间管理版权方法
Feb 22 PHP
php 地区分类排序算法
Jul 01 PHP
php去除字符串换行符示例分享
Feb 13 PHP
PHP实现的多彩标签效果代码分享
Aug 21 PHP
PHP实用函数分享之去除多余的0
Feb 06 PHP
PHP处理postfix邮件内容的方法
Jun 16 PHP
如何在旧的PHP系统中使用PHP 5.3之后的库
Dec 02 PHP
MAC下通过改apache配置文件切换php多版本的方法
Apr 26 PHP
yii2中LinkPager增加总页数和总记录数的实例
Aug 28 PHP
Thinkphp开发--集成极光推送
Sep 15 PHP
PHP PDO和消息队列的个人理解与应用实例分析
Nov 25 PHP
使用git迁移Laravel项目至新开发环境的步骤详解
Apr 06 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
《DOTA3》开发工作已经开始 《DOTA3》将代替《DOTA2》
2021/03/06 DOTA
BBS(php &amp; mysql)完整版(一)
2006/10/09 PHP
php5.3不能连接mssql数据库的解决方法
2014/12/27 PHP
PHP下载远程文件到本地存储的方法
2015/03/24 PHP
php实现的通用图片处理类
2015/03/24 PHP
微信支付开发订单查询实例
2016/07/12 PHP
php制作圆形用户头像的实例_自定义封装类源代码
2017/09/18 PHP
TP5框架页面跳转样式操作示例
2020/04/05 PHP
javascript smipleChart 简单图标类
2011/01/12 Javascript
初学js 新节点的创建 删除 的步骤
2011/07/04 Javascript
基于jquery打造的百分比动态色彩条插件
2012/09/19 Javascript
javaScript复制功能调用实现方案
2012/12/13 Javascript
JS实现窗口加载时模拟鼠标移动的方法
2015/06/03 Javascript
轻松使用jQuery双向select控件Bootstrap Dual Listbox
2015/12/13 Javascript
js的各种排序算法实现(总结)
2016/07/23 Javascript
基于JavaScript实现鼠标向下滑动加载div的代码
2016/08/31 Javascript
用自定义图片代替原生checkbox实现全选,删除以及提交的方法
2016/10/18 Javascript
移动端触摸滑动插件swiper使用方法详解
2017/08/11 Javascript
详解webpack引用jquery(第三方模块)的三种办法
2019/08/21 jQuery
echarts实现晶体球面投影的实例教程
2020/10/10 Javascript
Python对多属性的重复数据去重实例
2018/04/18 Python
python cs架构实现简单文件传输
2020/03/20 Python
Linux上使用Python统计每天的键盘输入次数
2019/04/17 Python
使用Flask-Cache缓存实现给Flask提速的方法详解
2019/06/11 Python
python读写csv文件并增加行列的实例代码
2019/08/01 Python
30秒学会30个超实用Python代码片段【收藏版】
2019/10/15 Python
python turtle工具绘制四叶草的实例分享
2020/02/14 Python
银行出纳岗位职责
2013/11/25 职场文书
总经理岗位职责描述
2014/02/08 职场文书
奥巴马英文演讲稿
2014/05/15 职场文书
篮球赛口号
2014/06/18 职场文书
体育运动会广播稿
2014/10/05 职场文书
单身申明具结书
2015/02/26 职场文书
初中军训感言
2015/08/01 职场文书
学校2016年全国助残日活动总结
2016/04/01 职场文书
公司年会主持词范文!
2019/05/07 职场文书