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 MessagePack介绍
Oct 06 PHP
php用正则表达式匹配URL的简单方法
Nov 12 PHP
PHP截取指定图片大小的方法
Dec 10 PHP
PHP提示Warning:phpinfo() has been disabled函数禁用的解决方法
Dec 17 PHP
php静态文件返回304技巧分享
Jan 06 PHP
ThinkPHP3.2.2的插件控制器功能
Mar 05 PHP
php查询whois信息的方法
Jun 08 PHP
php轻松实现文件上传功能
Mar 03 PHP
简单概括PHP的字符串中单引号与双引号的区别
May 07 PHP
php版微信公众平台实现预约提交后发送email的方法
Sep 26 PHP
PHP微信网页授权的配置文件操作分析
May 29 PHP
php 防护xss,PHP的防御XSS注入的终极解决方案
Apr 01 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生成EAN_13标准条形码实例
2013/11/13 PHP
php进行ip地址掩码运算处理的方法
2016/07/11 PHP
PHP实现带重试功能的curl连接示例
2016/07/28 PHP
微信网页授权(OAuth2.0) PHP 源码简单实现
2016/08/29 PHP
PHP实现的mysql读写分离操作示例
2018/05/22 PHP
php微信支付之公众号支付功能
2018/05/30 PHP
javascript中对对层的控制
2006/12/29 Javascript
javascript各种复制代码收集
2008/09/20 Javascript
jQuery级联操作绑定事件实例
2014/09/02 Javascript
javascript实现的右下角弹窗实例
2015/04/24 Javascript
JS封装cookie操作函数实例(设置、读取、删除)
2015/11/17 Javascript
基于Vue2的移动端开发环境搭建详解
2016/11/03 Javascript
JavaScript实现短信倒计时60s
2017/10/09 Javascript
react-native-video实现视频全屏播放的方法
2018/03/19 Javascript
vue删除html内容的标签样式实例
2018/09/13 Javascript
nodejs使用node-xlsx生成excel的方法示例
2019/08/22 NodeJs
vue 中固定导航栏的实例代码
2019/11/01 Javascript
微信小程序后端实现授权登录
2020/02/24 Javascript
Vant picker 多级联动操作
2020/11/02 Javascript
Python isinstance判断对象类型
2008/09/06 Python
Python高效编程技巧
2013/01/07 Python
Python实现删除某列中含有空值的行的示例代码
2020/07/20 Python
使用CSS3滤镜的filter:blur属性制作毛玻璃模糊效果的方法
2016/07/08 HTML / CSS
HTML5 body设置全屏背景图片的示例代码
2020/12/08 HTML / CSS
泰国网上购物:Shopee泰国
2018/09/14 全球购物
Helly Hansen工作服美国官方网上商店:为最恶劣的环境
2019/09/04 全球购物
客服端调用EJB对象的几个基本步骤
2012/01/15 面试题
体育教育个人自荐信范文
2013/12/01 职场文书
八年级英语教学反思
2014/01/09 职场文书
群众路线教育实践活动的心得体会
2014/09/03 职场文书
教育局党的群众路线教育实践活动整改方案
2014/09/20 职场文书
学习焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
2014年班组建设工作总结
2014/12/01 职场文书
走进科学观后感
2015/06/18 职场文书
简单且有用的Python数据分析和机器学习代码
2021/07/02 Python
在CSS中使用when/else的方法
2022/01/18 HTML / CSS