LoginSignup
9
2

More than 1 year has passed since last update.

【PHP8.1】あなたはどっち? array_merge VS unpacking(スプレッド演算子)

Last updated at Posted at 2022-09-13

PHP8.1がリリースされてそろそろ1年。PHP8.1のRelease Announcementを今更じっくりと眺めていたところ、見逃していた変更点を発見。

Array unpacking support for string-keyed arrays
https://www.php.net/releases/8.1/en.php

配列アンパックが連想配列をサポートするようになった、とのこと。
配列アンパックとは、一般的にいう『スプレッド演算子』『スプレッド構文』のことです。

アンパック例
$x = ['a' => 1, 'b' => 2];
$y = ['c' => 3, 'd' => 4];
$result = [...$x, ...$y];
// ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4]

これによって、array_mergeを完全にアンパックに置き換える事が可能になった、ということになりそう。
もうarray_mergeを使うこともなくなるかな、と思いつつ、念のためパフォーマンスを比較してみることに。

検証

比較用コード(PHP8.1.9)
// 1000個ほどの要素をもつ連想配列を2つ用意する
$str = join([...range(0, 9), ...range('a', 'z'), ...range('A', 'Z')]);
$arr1 = $arr2 = [];
for ($i = 0; $i < 1000; ++$i) {
	$arr1[str_shuffle($str)] = $i;
	$arr2[str_shuffle($str)] = $i;
}

// array_mergeを1万回実行するのに要した時間
$start = microtime(true);
for ($i = 0; $i < 10000; ++$i) {
	$tmp = array_merge($arr1, $arr2);
}
echo 'array_merge:' . (microtime(true) - $start) . "\n";

// アンパックを1万回実行するのに要した時間
$start = microtime(true);
for ($i = 0; $i < 10000; ++$i) {
	$tmp = [...$arr1, ...$arr2];
}
echo 'unpacking:' . (microtime(true) - $start) . "\n";
array_merge unpacking
1st 0.606 1.031
2nd 0.626 1.044
3rd 0.620 1.076
4th 0.613 1.046
5th 0.621 1.039

一般的には関数より構文のほうが処理速度が速いといわれていますが、意外な結果になりました。

どうしても納得できず・・・
2つの配列の要素数を100に減らしてみましたが、array_mergeの圧勝。
2つの配列を添字配列にしてみましたが、array_mergeの圧勝。
結合する配列数を増やしてみましたが、array_mergeの圧勝。

せめてメモリ使用量はアンパックに軍配が上がって欲しい・・・と
memory_get_peak_usageを仕込んでみましたが、array_mergeのほうがやや優れていました。

結局どっちを使えばいいの?

他にもいくつかのパターンを比較してみましたが、
すべてではないにしろ、パフォーマンスの面ではarray_mergeのほうが優れているという結果になりました。

特にパフォーマンスが重要な場面ではarray_mergeを使う選択肢はありそうですが、
この程度のパフォーマンス差であれば、どちらかにこだわる必要もないかなと。

個人的にはアンパックを積極的に使っていこうと思います。

ご指摘・ご意見などありましたら、ぜひコメントお願いします。

9
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
2