結論
追記:コメント欄要参照
array_merge
は要素数が増えるほどパフォーマンスが低下する。
キーが重要でなく、重複整数をキーを変え追加したいならば1
角括弧構文$array[] = 値
を使用すれば、パフォーマンスが低下しない
参考文献
配列結合演算子, array_merge, array_replace を徹底比較
お世話になっております。
すごく見やすいです。
やりたかったこと
preg_match_all
の一致したキーワードを重複を認めつつ1次元配列に集めたい。
並び順、キーは重要でない。
preg_match_all
の結果は第三引数の$array[0]
内に、整数キーで格納される。
+
では整数の重複が無視され、array_replace
では上書きされてしまう。
重複整数でも追加されるのはarray_merge
だけだったので、array_merge
にしたところ、回数が増えるごとに極端に遅くなってしまった。
検証コード
$start = microtime(true);
for ($i = 0, $all = array(); $i < 10000; ++$i) {
//$rand = rand();
$rand = '1234567890';
$matches = array();
preg_match_all('/123|456|789/', $rand, $matches);
$before = microtime(true);
$all = array_merge($all, $matches[0]);
if (($i % 1000) == 0) {
echo printf("%.12f", (microtime(true) - $before)) . PHP_EOL;
}
}
//var_dump($all);
echo "End\n";
echo printf("%.12f", (microtime(true) - $start)) . PHP_EOL;
//diff用
file_put_contents('/tmp/merge',print_r($all, true));
$start = microtime(true);
for ($i = 0, $all = array(); $i < 10000; ++$i) {
//$rand = rand();
$rand = '1234567890';
$matches = array();
preg_match_all('/123|456|789/', $rand, $matches);
$before = microtime(true);
foreach($matches[0] as $value) {
$all[] = $value;
}
if (($i % 1000) == 0) {
echo printf("%.12f", (microtime(true) - $before)) . PHP_EOL;
}
}
//var_dump($all);
echo "End\n";
echo printf("%.12f", (microtime(true) - $start)) . PHP_EOL;
//diff用
file_put_contents('/tmp/push',print_r($all, true));
結果
# php merge.php
0.00001382827814
0.00059795379614
0.00156402587914
0.00243592262314
0.00324916839614
0.00408887863214
0.00526213645914
0.00667285919214
0.00805711746214
0.00815606117214
End
48.14117693901115
# php push.php
0.00001621246314
0.00000190734914
0.00000095367414
0.00000095367414
0.00000214576714
0.00000095367414
0.00000095367414
0.00000119209314
0.00000095367414
0.00000309944214
End
0.05467796325714
# diff merge push -s
ファイルmergeとpushは同一
array_merge
が不利ないじわるな条件でしたが、
恐らくarray_merge
は添字振り直しで時間を食われている?
一方$array[] = 値
では処理時間に配列数は関係ないように見える。
出力自体は一緒なので、値だけ欲しければ$array[] = 値
が良さそう。
文字列キーが重複しないこと前提の場合、array_merge
と
foreeach($array as $key => $var) {
$all[$key] = $var
}
どちらが早いかも気になる。
キーワードと出現回数をカウントアップしたら結果配列の結合は不要じゃないかな?
そっちの方が遅いかな?
-
重複整数を無視、上書きしないならば ↩