熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> PHP編程 >> 正文

PHP數組交集的優化

2013-11-15 12:33:40  來源: PHP編程 

  

PHP數組交集的優化

  假設我們正在運營一個手機相關的網站用戶可以通過指定若干參數(如操作系統屏幕分辨率攝像頭像素等等)來篩選自己想要的手機不過由於手機的參數多且不同的手機其參數差異大所以參數表結構通常是縱表(一個參數是一行)而不是橫表(一個參數是一列)此時使用若干參數來取結果通常就是把每個單獨參數來取結果再一起取交集

  假定每個參數會包含一千個左右的唯一結果(id int)以此為前提來模擬生成一些數據

  

  

  <?php

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

    for ($i = ; $i < ; null) {
        $value = mt_rand( );

        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);
    }

    $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 = $j = ; $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

  intersect

  需要提醒大家的是array_intersect和intersect在功能上並不完全等價例子如下

  

  

  $param_a = array( );
$param_b = array( );

var_dump(
    array_intersect($param_a $param_b)
    intersect($param_a $param_b)
);

  

  array_intersect

  intersect

  也就是說如果在第一個數組參數中有重復元素的話則array_intersect會返回所有滿足條件的重復元素而不是僅僅返回一個有興趣的讀者可以變換一下參數順序再看結果

  再唠叨一下最初我寫intersect方法時大概寫成下面這個樣子

  

  

  <?php

function intersect() {
    if (func_num_args() < ) {
        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 > ) {
            $result[] = $value;
        }
    }

    return $result;
}

?>

  

  代碼更簡潔不過有一個弊端因為使用了array_merge所以當數組中元素非常多的時候占用的內存會比較大反之如果數組中元素不是非常多那麼此方法也是可行的

  參考Faster array_intersect


From:http://tw.wingwit.com/Article/program/PHP/201311/21179.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.