慎用php的array_search函数

array_search是phper使用频次很是高的一个数组函数,可是array_search也是常常被滥用的一个函数,好比假设下面这种业务场景,须要把两个大数组内相同的元素统计出来(恩,没错有个array_intersect函数能够完成这个工做,但这并不妨碍咱们讲这个例子)。php

若是使用array_search就是这种写法数组

$arr1 = ['假设他有100万个元素'];
$arr2 = ['假设他有100万个元素'];
$arr3 = [];
foreach ($arr1 as $v) {
    $k = array_search($v, $arr2);
    if ($k === false) {
        $arr3[] = $v;
    }
}

array_search的实现,php源码ext/standard/array.c,截取部分代码,宏的实现就不贴出来了,看名字也能猜出来它怎么实现的,就是循环遍历。架构

static inline void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{ */
{
    if (strict) {
        ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) {
            ……
        } ZEND_HASH_FOREACH_END();
    } else {
        if (Z_TYPE_P(value) == IS_LONG) {
            ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) {
                ……
            } ZEND_HASH_FOREACH_END();
        } else if (Z_TYPE_P(value) == IS_STRING) {
            ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) {
                ……
            } ZEND_HASH_FOREACH_END();
        } else {
            ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) {
                ……
            } ZEND_HASH_FOREACH_END();
         }
    }
    RETURN_FALSE;
}

因此上面这种实现的时间复杂度O(n²),这个时间复杂度是至关恐怖的。函数

而后,咱们看下另一种实现,把arr2的key和value转换下,因为hashmap的时间复杂度是O(1) ~ O(n)(大多数时候都是1),因此这个实现的时间复杂度O(n),有了质的提高,时间复杂度由二次时间变成了线性时间。性能

$arr1 = ['假设他有100万个元素'];
$arr2 = array_flip(['假设他有100万个元素']);
$arr3 = [];
foreach ($arr1 as $v) {
    if (isset($arr2[$v])) {
        $arr3[] = $v;
    }
}

咱们在作数据统计的时候,常常须要遇到相似的业务场景,能极大的提升程序的运行性能,可是这种写法也有它的局限性,好比value有重复的数据,因此没有万能银弹。code

更多架构、PHP、GO相关踩坑实践技巧请关注个人公众号:PHP架构师ip

相关文章
相关标签/搜索