您当前的位置: 首页 > 网站编程 > PHP教程 > PHP数组交集的优化

PHP数组交集的优化

作者:不详 来源:网络 发布时间: 2014-08-20 13:49 点击:
PHP数组交集的优化 假设我们正在运营一个手机相关的网站,用户可以通过指定若干参数(如操作系统,屏幕分辨率,摄像头像素等等)来筛选自己想要的手机。不过由于手机的参数多,且不同的手机其参数差异大,所以参数表结构通常是纵表(一个参数是一行),而不是横表(一

PHP数组交集的优化

  PHP数组交集的优化

  

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

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

  



  

  

  

  

  

  


  

<?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() < 2) {

         trigger_error('param error', E_USER_ERROR);

     }

     $args = func_get_args();

     foreach ($args AS $arg) {

         if (!is_array($arg)) {

             trigger_error('param error', E_USER_ERROR);

         }

     }

     $intersect = function($a, $b) {

         $result = array();

         $length_a = count($a);

         $length_b = count($b);

         for ($i = 0, $j = 0; $i < $length_a && $j < $length_b; null) {

             if($a[$i] < $b[$j]) {

                 $i++;

             } else if($a[$i] > $b[$j]) {

                 $j++;

             } else {

                 $result[] = $a[$i];

                 $i++;

                 $j++;

             }

         }

         return $result;

     };

     $result = array_shift($args);

     sort($result);

     foreach ($args as $arg) {

         sort($arg);

         $result = $intersect($result, $arg);

     }

     return $result;

  }

  $time = microtime(true);

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

  $time = microtime(true) - $time;

  echo "intersect: {$time}n";

  ?>

  



  



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

  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会返回所有满足条件的重复元素,而不是仅仅返回一个,有兴趣的读者可以变换一下参数顺序再看结果。

  再唠叨一下,最初我写intersect方法时,大概写成下面这个样子:

  

  

  

  

  

  

  


  

<?php

  function intersect() {

     if (func_num_args() < 2) {

         trigger_error('param error', E_USER_ERROR);

     }

     $args = func_get_args();

     foreach ($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', $args)

     );

     foreach ($data AS $value => $count) {

         if ($count > 1) {

             $result[] = $value;

         }

     }

     return $result;

  }

  ?>

  



  



  代码更简洁,不过有一个弊端,因为使用了array_merge,所以当数组中元素非常多的时候,占用的内存会比较大,反之如果数组中元素不是非常多,那么此方法也是可行的。

  



  参考:Faster array_intersect
分享到:
本文"PHP数组交集的优化"由远航站长收集整理而来,仅供大家学习与参考使用。更多网站制作教程尽在远航站长站。
顶一下
(0)
0%
踩一下
(0)
0%
[点击 次] [返回上一页] [打印]
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
关于本站 - 联系我们 - 网站声明 - 友情连接- 网站地图 - 站点地图 - 返回顶部
Copyright © 2007-2013 www.yhzhan.com(远航站长). All Rights Reserved .
远航站长:为中小站长提供最佳的学习与交流平台,提供网页制作与网站编程等各类网站制作教程.
官方QQ:445490277 网站群:26680406 网站备案号:豫ICP备07500620号-4