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
discuz 首页四格:最新话题+最新回复+热门话题+精华文章插件
Aug 19 PHP
php park、unpark、ord 函数使用方法(二进制流接口应用实例)
Oct 19 PHP
php 代码优化之经典示例
Mar 24 PHP
PHP缓存技术的多种方法小结
Aug 14 PHP
浅谈php正则表达式中的非贪婪模式匹配的使用
Nov 25 PHP
curl和libcurl的区别简介
Jul 01 PHP
WordPres对前端页面调试时的两个PHP函数使用小技巧
Dec 22 PHP
PHP MYSQL简易交互式站点开发
Dec 27 PHP
CI框架(CodeIgniter)公共模型类定义与用法示例
Aug 10 PHP
原生JS实现Ajax通过GET方式与PHP进行交互操作示例
May 12 PHP
详解PHP版本兼容之openssl调用参数
Jul 25 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目录与文件操作
2011/12/30 PHP
详解YII关联查询
2016/01/10 PHP
Eclipse PHPEclipse 配置的具体步骤
2017/08/08 PHP
JavaScript中的排序算法代码
2011/02/22 Javascript
Jquery中给animation加更多的运作效果实例
2013/09/05 Javascript
JQuery实现倒计时按钮具体方法
2013/11/14 Javascript
jQuery操作input值的各种方法总结
2013/11/21 Javascript
SuperSlide2实现图片滚动特效
2014/06/20 Javascript
Node.js异步I/O学习笔记
2014/11/04 Javascript
jQuery使用CSS()方法给指定元素同时设置多个样式
2015/03/26 Javascript
jQuery实现区域打印功能代码详解
2016/06/17 Javascript
jQuery插件扩展实例【添加回调函数】
2016/11/26 Javascript
JS区分Object与Aarry的六种方法总结
2017/02/27 Javascript
Vue2.0学习之详解Vue 组件及父子组件通信
2017/12/12 Javascript
Vue.js 时间转换代码及时间戳转时间字符串
2018/10/16 Javascript
详解如何提升JSON.stringify()的性能
2019/06/12 Javascript
微信公众号平台接口开发 获取access_token过程解析
2019/08/14 Javascript
JavaScript 实现HTML DOM增删改查操作的常见方法详解
2020/01/04 Javascript
Python调用C# Com dll组件实战教程
2017/10/12 Python
python编程培训 python培训靠谱吗
2018/01/17 Python
python 获取图片分辨率的方法
2019/01/08 Python
用Q-learning算法实现自动走迷宫机器人的方法示例
2019/06/03 Python
python3的print()函数的用法图文讲解
2019/07/16 Python
基于python实现从尾到头打印链表
2019/11/02 Python
python实现滑雪游戏
2020/02/22 Python
Django xadmin安装及使用详解
2020/10/26 Python
CSS3地图动态实例代码(圆圈向外扩散)
2018/06/15 HTML / CSS
Aveda美国官网:天然护发产品、洗发水、护发素和沙龙
2016/12/09 全球购物
印度和世界各地的精美产品:Ikka Dukka
2018/02/12 全球购物
美国地毯购买网站:Rugs USA
2019/02/23 全球购物
TecoBuy澳大利亚:在线电子和小工具商店
2020/06/25 全球购物
美国最大最全的亚洲购物网站:美国亚米网(Yamibuy)
2020/05/05 全球购物
财务管理专业毕业生求职信范文
2013/09/21 职场文书
优秀员工事迹材料
2014/12/20 职场文书
2015年基层党建工作汇报材料
2015/06/25 职场文书
Golang 字符串的常见操作
2022/04/19 Golang