`

php in_array的低性能

    博客分类:
  • PHP
阅读更多

PS:原创文章,如需转载,请注明出处,谢谢!     

本文地址:http://flyer0126.iteye.com/blog/2270090

 

PHP7最近推出了,首要说的就是性能方面的提升。对于in_array()一直诟病很多,至于性能有多差,先简单测试一下,看看数据。

测试程序如下:

<?php
/**
 * 获取当前时间戳(毫秒级)
 * @return float
 */
function microtime_float(){
    list($usec, $sec) = explode(' ', microtime());
    return ((float)$usec + (float)$sec);
}

/**
 * 数组初始化
 */
$int_arr = $str_arr = [];
for($i=0; $i<200000; $i++){
    $int_arr[] = $i;
    $str_arr[] = "{$i}";
}

$time_start = microtime_float();
// 具体操作
for($j=0; $j<3000; $j++){
    if(in_array(18000, $int_arr)){
        continue;
    }
//    if(isset($int_arr[$key])){
//        continue;
//    }
}
$time_end = microtime_float();
echo '消耗时间:'.($time_end - $time_start);

 测试结果

in_array 方式
1. 字符型字符串
// 3k 消耗时间:1.0687351226807
// 3w 消耗时间:10.569030046463
2. int 型字符串
// 3k 消耗时间:1.0500609874725
// 3w 消耗时间:10.290988922119

isset 方式
1. 字符型字符串
// 3k 消耗时间:0.00010299682617188
// 3w 消耗时间:0.00089907646179199
2. int 型字符串
// 3k 消耗时间:0.00010108947753906
// 3w 消耗时间:0.00085687637329102

结合上面测试数据,两种方式的性能差距还是挺明显的。

利用ltrace来跟踪进程调用库函数的情况:

$ ltrace -c /usr/local/php/bin/php test.php


 看到库函数__strtol_internal的调用非常之频繁,这个库函数__strtol_internal是原来是strtol的别名,简单的说就是把字符串转换成长整形,可以推测PHP引擎已经检测到这是一个字符串型的数字,所以期望将他们转换成长整型来比较,这个转换过程中消耗了太多时间,我们再次执行:

$ ltrace -e "__strtol_internal" /usr/local/php/bin/php test.php

 可以轻松抓到大量下图这样的调用,到此,问题找到了,in_array这种松比较,会将两个字符型数字串先转换为长整型再进行比较,却不知性能就耗在这上面了。


 
知道了症结所在,我们解决的办法就很多了,最简单的就是为in_array加第三个参数为true,即变为严格比较,同时还要比较类型,这样避免了PHP自作聪明的转换类型,跑起来果然快多了,代码如下:

in_array(search,array,type)
参考上例,如改为:
in_array(18000, $int_arr, true);
in_array('18000', $str_arr, true);
分别执行3k次的消耗时间分别为:0.88052606582642、0.8897430896759

 总结一下,大数组的查询,用in_array函数是个糟糕的选择。应该尽量用isset函数来替代 。in_array函数的复杂度是O(n),而isset函数的复杂度是O(1)。

  • 大小: 14.2 KB
  • 大小: 10.1 KB
分享到:
评论

相关推荐

    遭遇php的in_array低性能问题

    标题中的“遭遇php的in_array低性能问题”指的是在PHP编程中使用`in_array`函数时遇到的性能瓶颈。描述中提到,尽管PHP的性能在不断提升,但如果使用不当,仍可能遇到由于内部实现细节导致的性能问题。这个问题是...

    php中使用in_array() foreach array_search() 查找数组是否包含时的性能对比

    总结起来,对于PHP中判断数组是否包含特定值的操作,`in_array()`和`array_search()`提供了更好的性能,特别是处理大量数据时,而`foreach`循环更适合简单的遍历任务。在编写代码时,应根据实际情况权衡效率和可读性...

    php判断数组元素中是否存在某个字符串的方法

    对于非关联数组,`in_array()` 和 `array_search()` 的内存使用可能会更低。 **总结** - `in_array()` 用于查找值,并可以进行类型检查。 - `array_key_exists()` 用于检查特定键是否存在,不适用于查找值。 - `...

    深思 PHP 数组遍历的差异(array_diff 的实现)

    题目中给出了三种不同的实现方法,分别是原始的双层循环、使用 `in_array` 函数以及通过 `array_flip` 函数优化的版本。 首先,我们来看第一种实现,这是一个简单的双层循环,将第一个数组的每个元素与第二个数组...

    php 查找数组元素提高效率的方法详解

    然而,`in_array()`在处理包含大量元素的数组时效率可能会比较低。 例如,在有10万个元素的数组中进行1000次的`in_array()`查找,可能会消耗大约2秒的时间,如文中所示的代码执行示例。效率低下的原因在于`in_array...

    马拉松,跑步,赛事报名系统

    是一个针对体育赛事及其他通用活动开发的网上报名系统,支持公众号及小程序 免费,高性能,可靠 赛事报名系统 省钱 对于第三方支付平台的高额手续费,我们只需支付收款平台的低额手续费 我们是PHP/MYSQL开发的报名...

    马拉松,跑步,赛事报名系统.zip

    是一个针对体育赛事及其他通用活动开发的网上报名系统,支持公众号及小程序 免费,高性能,可靠 赛事报名系统 省钱 对于第三方支付平台的高额手续费,我们只需支付收款平台的低额手续费 我们是PHP/MYSQL开发的报名...

    php数组函数序列之array_intersect() 返回两个或多个数组的交集数组

    `array_intersect()` 是 PHP 中一个非常实用的数组处理函数,它的主要作用是找出两个或多个数组之间的交集。交集是指存在于所有数组中的相同元素。这个函数在处理多个数据源时,尤其在需要筛选出共同元素的情况下...

    PHP程序优化总结.pdf

    - 有时候内置函数如`in_array()`可能比自定义函数效率要低,例如文档中提到的`fast_in_array()`函数,它使用二分查找算法,比`in_array()`要快五倍,因此在性能关键的代码中可以替换原生函数以提高效率。...

    php删除二维数组中的重复值方法

    可以考虑使用更高级的数据结构,如哈希表(关联数组),或者使用`array_reduce()`配合自定义比较函数来优化性能。 总之,`a_array_unique`函数提供了一种实用的方式去删除二维数组中的重复子数组。然而,实际应用中...

    php批量删除数据程序代码_.docx

    然而,这种方法效率较低,因为每次循环都会执行一次数据库查询。为了优化,可以将所有ID合并为一个逗号分隔的字符串,然后在一个`IN`语句中执行删除操作,如下: ```php $ids = implode(',', $_POST['del_id']); $...

    PHP的数组中提高元素查找与元素去重的效率的技巧解析

    但是,当`haystack`数组很大时,使用`in_array()`的效率会相对较低。这主要是因为`in_array()`需要遍历整个数组来进行匹配。为了提高效率,可以使用`array_flip()`和`isset()`方法组合。`array_flip()`函数会交换...

    PHP常用排序算法实例小结【基本排序,冒泡排序,快速排序,插入排序】

    插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。 ```php function sort_insertion($arr){ ...

    php笔记之:有规律大文件的读取与写入的分析

    当需要检查数组中是否存在某个特定值时(比如 44444),使用 in_array() 函数可能效率较低。文章中提出了一个聪明的方法:将数组翻转过来,将每个值作为键,每个键对应的值都设为 1。这样做的好处是,通过检查某个键...

    PHPCMS整站代码分析讲解.doc

    `unset()`函数则用于清空一些旧的全局变量,如`$HTTP_ENV_VARS`和`$HTTP_POST_VARS`,这是因为在PHP 4.1.0以上版本,这些变量已经被`$_REQUEST`等新变量所替代,清空它们能避免低版本PHP的安全问题,如变量注入。...

    php购物车实现方法

    `require 'lib.inc.php';`引用了一个包含函数`LoadProducts()`的库文件,这个函数负责从TXT文件加载产品数据并存储在`$master_products_list`数组中。这样,我们可以根据用户的选择找到对应的产品信息。 3. **查找...

    数据结构和算法分析的PHP描述

    平衡树是一种特殊的二叉搜索树,它确保了树的高度尽可能地低,从而保证了查找、插入和删除操作的时间复杂度为O(log n)。 #### 堆(Heap) **概述** 堆是一种完全二叉树结构,它可以是最大堆也可以是最小堆。堆的主要...

    php字符编码转换之gb2312转为utf8

    总结来说,对于PHP中的GB2312到UTF-8的编码转换,可以优先考虑使用`iconv`,因为它在性能上更优。但当遇到转换异常或不确定源编码时,可以借助`mb_convert_encoding`,利用其自动检测功能。在实际开发中,确保正确...

Global site tag (gtag.js) - Google Analytics