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 相关文章推荐
新闻分类录入、显示系统
Oct 09 PHP
php实现的MySQL通用查询程序
Mar 11 PHP
php XMLWriter类的简单示例代码(RSS输出)
Sep 30 PHP
深入PHP运行环境配置的详解
Jun 04 PHP
php结合ajax实现赞、顶、踩功能实例
May 12 PHP
教你如何解密 “ PHP 神盾解密工具 ”
Jun 20 PHP
深入理解PHP中的Streams工具
Jul 03 PHP
PHP单例模式详解及实例代码
Dec 21 PHP
php中的抽象方法和抽象类
Feb 14 PHP
php 删除指定文件夹的实例讲解
Jul 25 PHP
关于Yii中模型场景的一些简单介绍
Sep 22 PHP
php装饰者模式简单应用案例分析
Oct 23 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
PHP中怎样保持SESSION不过期 原理及方案介绍
2013/08/08 PHP
php图片处理函数获取类型及扩展名实例
2014/11/19 PHP
YII2 实现多语言配置的方法分享
2017/01/11 PHP
Yii2中简单的场景使用介绍
2017/06/02 PHP
php实现往pdf中加数字签名操作示例【附源码下载】
2018/08/07 PHP
CSS心形加载的动画源码的实现
2021/03/09 HTML / CSS
js中的replace方法使用介绍
2013/10/28 Javascript
jQuery常用数据处理方法小结
2015/02/20 Javascript
jQuery实现摸拟alert提示框
2016/05/22 Javascript
Angular Module声明和获取重载实例代码
2016/09/14 Javascript
easyUI实现(alert)提示框自动关闭的实例代码
2016/11/07 Javascript
JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题
2016/12/23 Javascript
seajs中模块依赖的加载处理实例分析
2017/10/10 Javascript
JavaScript实现数字前补“0”的五种方法示例
2019/01/03 Javascript
详解webpack打包vue项目之后生成的dist文件该怎么启动运行
2019/09/06 Javascript
解决layui下拉框监听问题(监听不到值的变化)
2019/09/28 Javascript
Vue解析带html标签的字符串为dom的实例
2019/11/13 Javascript
vue:el-input输入时限制输入的类型操作
2020/08/05 Javascript
python中根据字符串调用函数的实现方法
2016/06/12 Python
详解python中的文件与目录操作
2017/07/11 Python
Python模拟用户登录验证
2017/09/11 Python
python实现隐马尔科夫模型HMM
2018/03/25 Python
pip install urllib2不能安装的解决方法
2018/06/12 Python
python实现年会抽奖程序
2019/01/22 Python
Python3实现mysql连接和数据框的形成(实例代码)
2020/01/17 Python
解决TensorFlow GPU版出现OOM错误的问题
2020/02/03 Python
将labelme格式数据转化为标准的coco数据集格式方式
2020/02/17 Python
jupyter note 实现将数据保存为word
2020/04/14 Python
英国奢华护肤、美容和Spa品牌:Temple Spa
2019/11/02 全球购物
办公室副主任岗位职责
2013/11/25 职场文书
大一新生军训时的自我评价分享
2013/12/05 职场文书
日语专业个人求职信范文
2014/02/02 职场文书
2015年个人实习工作总结
2015/05/28 职场文书
预备党员介绍人意见
2015/06/01 职场文书
Vue详细的入门笔记
2021/05/10 Vue.js
深入理解CSS 中 transform matrix矩阵变换问题
2021/08/30 HTML / CSS