PHP配列交差の最適化
携帯電話関連の Web サイトを運営しているとします。ユーザーは、いくつかのパラメーター (オペレーティング システム、画面解像度、カメラのピクセルなど) を指定して、必要な携帯電話をフィルタリングできるとします。ただし、携帯電話には多くのパラメータがあり、携帯電話ごとにパラメータが大きく異なるため、パラメータ テーブルの構造は通常、水平テーブル (1 パラメータが 1 列) ではなく、垂直テーブル (1 パラメータが 1 行) になります。 、結果を取得するために複数のパラメータが使用されます。通常は、それぞれのパラメータを取得して結果を取得し、共通部分を取得します。
各パラメータには約 1,000 個の一意の結果 (id int) が含まれると想定し、これを前提としてデータをシミュレートおよび生成します。
<?php<font face="新宋体" size="2">
<br>
$rand = function() {<br>
$result = array();<br>
<br>
for ($i = 0; $i
$value = mt_rand(1, 10000);<br>
<br>
If (!isset($result[$value])) {<br>
$result[$value] = null;<br>
$i++;<br>
}<br>
}<br>
<br>
array_keys($result) を返します;<br>
};<br>
<br>
$param_a = $rand();<br>
$param_b = $rand();<br>
<br>
?><br></font>
|
注: テスト データ セットが小さすぎる場合、結論に一貫性がなくなる可能性があります。まず、PHP の組み込みメソッド array_intersect によって達成されるパフォーマンスを見てみましょう。
<?php<font face="新宋体" size="2">
<br>
$time = マイクロタイム(true);<br>
<br>
$result = array_intersect($param_a, $param_b);<br>
<br>
$time = microtime(true) - $time;<br>
<br>
echo "array_intersect: {$time}n";<br>
<br>
?><br></font>
|
カスタム メソッドの交差によって達成されるパフォーマンスを見てみましょう:
<font face="新宋体" size="2"><?php<br>
<br>
関数 intersect() {<br>
if (func_num_args()
trigger_error('パラメータエラー', E_USER_ERROR);<br>
}<br>
<br>
$args = func_get_args();<br>
<br>
foreach ($args AS $arg) {<br>
if (!is_array($arg)) {<br>
trigger_error('パラメータエラー', E_USER_ERROR);<br>
}<br>
}<br>
<br>
$intersect = function($a, $b) {<br>
$result = array();<br>
<br>
$length_a = count($a);<br>
$length_b = count($b);<br>
<br>
for ($i = 0, $j = 0; $i
if($a[$i] < $b[$j]) {<br>
$i++;<br>
} else if($a[$i] > $b[$j]) {<br>
$j++;<br>
} その他 {<br>
$result[] = $a[$i];<br>
$i++;<br>
$j++;<br>
}<br>
}<br>
<br>
$result を返します;<br>
};<br>
<br>
$result = array_shift($args);<br>
<br>
並べ替え($result);<br>
<br>
foreach ($arg を $arg として) {<br>
ソート($arg);<br>
<br>
$result = $intersect($result, $arg);<br>
}<br>
<br>
$result を返します;<br>
}<br>
<br>
$time = マイクロタイム(true);<br>
<br>
$result = intersect($param_a, $param_b);<br>
<br>
$time = microtime(true) - $time;<br>
<br>
echo "交差: {$time}n";<br>
<br>
?></font>
|
直感的には、組み込み関数の方がカスタム関数よりも速いと思いますが、この場合、結果はまったく逆になります。
array_intersect: 0.023918151855469
交差: 0.0026049613952637
array_intersect と intersect は機能的に完全に同等ではないことを皆さんに思い出していただく必要があります。例は次のとおりです。
$param_a = 配列(1, 2, 2);<font face="新宋体" size="2">
$param_b = 配列(1, 2, 3);<br>
<br>
var_dump(<br>
Array_intersect($param_a, $param_b),<br>
交差($param_a, $param_b)<br>
);<br></font>
|
array_intersect: 1、2、2
交差: 1、2
言い換えると、最初の配列パラメータに繰り返し要素がある場合、array_intersect は 1 つだけではなく、条件を満たすすべての繰り返し要素を返します。興味のある読者はパラメータの順序を変更して結果を確認できます。
もう一度話しましょう。最初に intersect メソッドを書いたときは、おそらく次のようになりました。
<?php<font face="新宋体" size="2">
<br>
関数 intersect() {<br>
If (func_num_args()
trigger_error('パラメータエラー', E_USER_ERROR);<br>
}<br>
<br>
$args = func_get_args();<br>
<br>
foreach ($args AS $arg) {<br>
If (!is_array($arg)) {<br>
trigger_error('パラメータエラー', E_USER_ERROR);<br>
}<br>
}<br>
<br>
$result = array();<br>
<br>
$data = array_count_values(<br>
call_user_func_array('array_merge', $args)<br>
);<br>
<br>
foreach ($data AS $value => $count) {<br>
if ($count > 1) {<br>
$result[] = $value;<br>
}<br>
}<br>
<br>
$result を返します;<br>
}<br>
<br>
?><br></font>
|
コードはより簡潔ですが、array_merge を使用するため、配列内の要素が非常に多い場合、逆に占有されるメモリが比較的大きくなります。であれば、この方法も実現可能です。
参考: より高速なarray_intersect
http://www.bkjia.com/PHPjc/371635.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/371635.html技術記事 PHP 配列交差の最適化 携帯電話関連の Web サイトを運営しているとします。ユーザーは、いくつかのパラメーター (オペレーティング システム、画面解像度、カメラのピクセルなど) を指定してフィルターをかけることができます。