慎用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

相關文章
相關標籤/搜索