Если бы у меня был массив целых чисел со знаком, например:
Array ( [0] => -3 [1] => 1 [2] => 2 [3] => 3 [4] => 3 )
Чтобы получить уникальные значения, я бы инстинктивно использовал array_unique
но после рассмотрения я мог бы выполнить array_flip
дважды, что будет иметь тот же эффект, и я думаю, что это будет быстрее?
array_unique
O (n log n) из-за операции сортировки, которую он использует
array_flip
O (n)
Правильно ли я в своих предположениях?
ОБНОВЛЕНИЕ / ПРИМЕР:
$intArray1 = array(-4,1,2,3); print_r($intArray1); $intArray1 = array_flip($intArray1); print_r($intArray1); $intArray1 = array_flip($intArray1); print_r($intArray1); Array ( [0] => -3 [1] => 1 [2] => 2 [3] => 3 [4] => 3 ) Array ( [-3] => 0 [1] => 1 [2] => 2 [3] => 4 ) Array ( [0] => -3 [1] => 1 [2] => 2 [4] => 3 )
Я оценил это для вас: CodePad
Ваша интуиция в этом была правильной!
$test=array(); for($run=0; $run<1000; $run++) $test[]=rand(0,100); $time=microtime(true); for($run=0; $run<100; $run++) $out=array_unique($test); $time=microtime(true)-$time; echo 'Array Unique: '.$time."\n"; $time=microtime(true); for($run=0; $run<100; $run++) $out=array_keys(array_flip($test)); $time=microtime(true)-$time; echo 'Keys Flip: '.$time."\n"; $time=microtime(true); for($run=0; $run<100; $run++) $out=array_flip(array_flip($test)); $time=microtime(true)-$time; echo 'Flip Flip: '.$time."\n";
Вывод:
Array Unique: 1.1829199790955 Keys Flip: 0.0084578990936279 Flip Flip: 0.0083951950073242
Обратите внимание, что array_keys(array_flip($array))
будет давать новые значения ключей по порядку, что во многих случаях может быть тем, что вы хотите (идентично, но намного быстрее, чем array_values(array_unique($array))
), тогда как array_flip(array_flip($array))
идентичен (за исключением гораздо более быстрого) array_unique($array)
где ключи остаются неизменными.
Ничто не лучше, чем запуск собственного теста.
➜ 8321620 cat first.php <?php $arr = array(-3, 1, 2, 3, 3); for($i = 0; $i <= 1000000; $i++) { array_unique($arr); } ➜ 8321620 time php first.php php first.php 3.24s user 0.01s system 99% cpu 3.251 total ➜ 8321620 cat second.php <?php $arr = array(-3, 1, 2, 3, 3); for($i = 0; $i <= 1000000; $i++) { array_flip(array_flip($arr)); } ➜ 8321620 time php second.php php second.php 1.50s user 0.01s system 99% cpu 1.514 total
Обновление: массив с 1000 элементами.
➜ 8321620 cat first.php <?php $arr = array(); for($i = 0; $i <= 1000; $i++) { $arr[] = rand(0, 1000); } for($i = 0; $i <= 10000; $i++) { array_unique($arr); } ➜ 8321620 time php first.php php first.php 27.50s user 0.03s system 99% cpu 27.534 total ➜ 8321620 cat second.php <?php $arr = array(); for($i = 0; $i <= 1000; $i++) { $arr[] = rand(0, 1000); } for($i = 0; $i <= 10000; $i++) { array_flip(array_flip($arr)); } ➜ 8321620 time php second.php php second.php 1.59s user 0.01s system 99% cpu 1.604 total
Так что да, ваше предположение было правильным.
Внимание: этот метод НЕ является заменой для array_unique (). Он работает только для массивов со значениями, которые являются действительными ключами. (например: string, integer, вещи могут быть перенесены в int). И, конечно, не работает для массивов объектов.
$input = [true, false, 1, 0, 1.2, "1", "two", "0"]; var_export(array_unique($input)); array ( 0 => true, 1 => false, 3 => 0, 4 => 1.2, 6 => 'two', )
против:
var_export(array_keys(array_flip($input))); PHP Warning: array_flip(): Can only flip STRING and INTEGER values! in php shell code on line 1 array ( 0 => 1, 1 => 0, 2 => 'two', )
вам придется использовать
array_keys( array_flip( $array ) );
что потребует больше времени
Я бы пошел на array_unique
. Он имеет дополнительное преимущество, объясняя, что происходит.