技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> PHP --> PHP数组交集的优化

PHP数组交集的优化

浏览:2067次  出处信息

假设我们正在运营一个手机相关的网站,用户可以通过指定若干参数(如操作系统,屏幕分辨率,摄像头像素等等)来筛选自己想要的手机。不过由于手机的参数多,且不同的手机其参数差异大,所以参数表结构通常是纵表(一个参数是一行),而不是横表(一个参数是一列),此时使用若干参数来取结果,通常就是把每个单独参数来取结果,再一起取交集。

假定每个参数会包含一千个左右的结果,以此为前提来模拟生成一些数据:

以下是代码片段:
<?php

$rand = function() {
    $result = array();

    for ($i = 0; $i < 1000; null) {
        $value = mt_rand(1, 10000);

        if (!isset($result[$value])) {
            $result[$value] = null;
            $i++;
        }
    }

    return array_keys($result);
};

$param_a = $rand();
$param_b = $rand();

?>

注:留意数据量的大小,以几百到几万为宜。

先来看看通过PHP内置方法array_intersect实现的性能:

以下是代码片段:
<?php

$time = microtime(true);

$result = array_intersect($param_a, $param_b);

$time = microtime(true) - $time;

echo "array_intersect: {$time}\n";

?>

再来看看通过自定义方法intersect实现的性能:

以下是代码片段:
<?php

function intersect() {
    if (!func_num_args()) {
        trigger_error(’param error’, E_USER_ERROR);
    }

    foreach (func_get_args() AS $arg) {
        if (!is_array($arg)) {
            trigger_error(’param error’, E_USER_ERROR);
        }
    }

    $result = array();

    $data = array_count_values(
        call_user_func_array(’array_merge’, func_get_args())
    );

    foreach ($data AS $value => $count) {
        if ($count > 1) {
            $result[] = $value;
        }
    }

    return $result;
}

$time = microtime(true);

$result = intersect($param_a, $param_b);

$time = microtime(true) - $time;

echo "intersect: {$time}\n";

?>

注:如果数组元素的数量很大的话,array_merge的时候可能会溢出。

直觉上,我们肯定会认为内置函数快于自定义函数,但本例中结果恰恰相反:

  • array_intersect: 0.023918151855469
  • intersect: 0.0026049613952637

这是因为array_intersect和intersect的功能并不完全等价,看下面的例子:

以下是代码片段:
$param_a = array(1, 2, 2);
$param_b = array(1, 2, 3);

var_dump(
    array_intersect($param_a, $param_b),
    intersect($param_a, $param_b)
);
  • array_intersect: 1, 2, 2
  • intersect: 1, 2

也就是说,如果在第一个数组参数中有重复元素的话,则array_intersect会返回所有满足条件的重复元素,而不是仅仅返回一个,有兴趣的读者可以变换一下参数顺序再看结果。

实际使用中,很多情况下我们都能保证数组参数没有重复元素,交集其实就是求合并数组中元素数量大于一的集合,此时在速度上array_intersect就显得鸡肋了。

建议继续学习:

  1. 为什么数组标号是从0开始的?    (阅读:4938)
  2. C语言结构体里的成员数组和指针    (阅读:4852)
  3. 将数组定义为常量    (阅读:4563)
  4. Tips of Linux C programming    (阅读:3964)
  5. xml转数组的方法    (阅读:3489)
  6. javascript扩展Array(数组)类    (阅读:3233)
  7. 动态数组的 C 实现    (阅读:3109)
  8. php数组排序    (阅读:3010)
  9. javascript数组排序的问题    (阅读:2950)
  10. 关于Cannot use a scalar value as an array的解决办法    (阅读:2889)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1