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