array_unique
と、array_flip
2回のどちらの方が早いかについてなんとなく検証してみました。
きっかけ
以前、先輩エンジニアに「array_unique
よりもarray_flip
2回の方が早いらしいよ」と聞いたことがありました。
ふと思い出し、調べたら日本語の記事もほとんど見つからなかったのでまとめようと思います。
array_unique と array_flip
array_unique
array_unique
は、配列を入力とし、値の重複がない新しい配列を返す関数です。
$a = array (0, 1, 0, 2, 3, 4, 6, 6, 2); //これが
$b = array_unique($a); //こうすると
print_r($b);
------
こうなる
Array
(
[0] => 0
[1] => 1
[3] => 2
[4] => 3
[5] => 4
[6] => 6
)
array_flip
array_flip
は、配列を入力とし、配列のキーと値を入れ替えた値を返します。
$a = array ("トマト", "人参", "なす","ピーマン"); //これが
$b = array_flip($a); //こうすると
print_r($b);
------
こうなる
Array
(
[トマト] => 0
[人参] => 1
[なす] => 2
[ピーマン] => 3
)
配列のキーはユニークではなくてはいけません。
そのため、もし仮に$a
の要素の値に重複が生じていたら、重複していたものは削除されます。
$a = array ("トマト", "人参", "ピーマン", "なす","ピーマン", "トマト",); //これが
$b = array_flip($a); //こうすると
print_r($b);
------
こうなる
Array
(
[トマト] => 0
[人参] => 1
[なす] => 2
[ピーマン] => 3
)
従って、array_flip
を使った結果にもう一度array_flip
を使うと
$a = array ("トマト", "人参", "ピーマン", "なす","ピーマン", "トマト",); //これが
$b = array_flip(array_flip($a)); //こうすると
print_r($b);
------
こうなる
Array
(
[5] => トマト
[1] => 人参
[4] => ピーマン
[3] => なす
)
array_uniqueと同じように、全ての要素がユニークな配列ができました。
速度検証
array_unique
とarray_flip
2回のどちらも同じように、配列の重複した値を削除することが確認できたところで、
両者の速度検証を行ってみます。
1回目
こんな感じのコードにしました。
<?php
$a = array();
for ($i = 0; $i < 500; $i++) {
$a[] = $i;
}
$b = array();
for ($i = 0; $i < 100; $i++) {
$b[] = $i;
}
// 0~500の値がある配列があり、0~100の値が重複している。
$c = array_merge($a, $b);
// array_unique
$time_start = microtime(true);
$d = array_unique($c);
$time = microtime(true) - $time_start;
$time = sprintf("%.13f", $time);
echo "array_unique => {$time} 秒\n";
// array_flip2回
$time_start = microtime(true);
$d = array_flip(array_flip($c));
$time = microtime(true) - $time_start;
$time = sprintf("%.13f", $time);
echo "array_flip2回 => {$time} 秒\n";
結果
- array_unique: 0.0005168914795 秒
- array_flip2回: 0.0000481605530 秒
array_flipの方が早いです。
2回目
配列の要素数が少ないだけかもしれないので、もう少し要素を増やして計測してみます。
<?php
$a = array();
for ($i = 0; $i < 300000; $i++) {
$a[] = $i;
}
$b = array();
for ($i = 0; $i < 100000; $i++) {
$b[] = $i;
}
// 0~300000の値がある配列があり、0~100000の値が重複している。
$c = array_merge($a, $b);
// array_unique
$time_start = microtime(true);
$d = array_unique($c);
$time = microtime(true) - $time_start;
$time = sprintf("%.13f", $time);
echo "array_unique => {$time} 秒\n";
// array_flip2回
$time_start = microtime(true);
$d = array_flip(array_flip($c));
$time = microtime(true) - $time_start;
$time = sprintf("%.13f", $time);
echo "array_flip2回 => {$time} 秒\n";
結果
- array_unique: 0.5305528640747 秒
- array_flip2回: 0.0351331233978 秒
ダントツでarray_flip2回の方が早いですね....
まとめ
2つのメソッドの速度計測を行い、array_uniqueよりもarrray_flip2回の方が本当に早かったことが確認できました。
こんなに速度が違ったとは...
厳密には、もっとたくさんの要素を重複させたりなどで計測を行って確かめてみるのが良いかもしれません。
ありがとうございました。