IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

PHP数组交集的优化

火丁笔记 2011-01-30 03:25:15 累计浏览 2,743 次
本机暂存

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

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

以下是代码片段:
<?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. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 使用gettext来支持PHP的多语言 (累计阅读 39,270)
  2. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  3. Paypal接口详细代码(PHP版,非API接口) (累计阅读 19,408)
  4. 我的PHP,Python和Ruby之路 (累计阅读 13,150)
  5. include(“./file.php”)和include(“file.php”)区别 (累计阅读 12,791)
  6. 15个最好的免费开源电子商务平台 (累计阅读 12,541)
  7. Redis消息队列的若干实现方式 (累计阅读 12,088)
  8. 到底什么是MVC? (累计阅读 11,870)
  9. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,709)
  10. Rolling cURL: PHP并发最佳实践 (累计阅读 11,488)