Этот вопрос предназначен только для меня, поскольку мне всегда нравится писать оптимизированный код, который может работать и на дешевых медленных серверах (или серверах с ОЧЕНЬ интенсивным трафиком).
Я огляделась и не нашла ответа. Мне было интересно, что быстрее между этими двумя примерами, имея в виду, что ключи массива в моем случае не важны (естественно, псевдокод):
<?php
$a = array();
while($new_val = 'get over 100k email addresses already lowercased'){
if(!in_array($new_val, $a){
$a[] = $new_val;
//do other stuff
}
}
?>
<?php
$a = array();
while($new_val = 'get over 100k email addresses already lowercased'){
if(!isset($a[$new_val]){
$a[$new_val] = true;
//do other stuff
}
}
?>
Поскольку суть вопроса не в конфликте массивов, я хотел бы добавить, что если вы боитесь столкновения вставок $a[$new_value]
, вы можете использовать $a[md5($new_value)]
. он по-прежнему может вызывать коллизии, но устранит возможную DoS-атаку при чтении из файла, предоставленного пользователем ( http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html )
php
performance
micro-optimization
Фабрицио
источник
источник
Ответы:
Ответы пока точны. Использование
isset
в этом случае быстрее, потому чтоin_array
должен проверять каждое значение, пока не найдет совпадение.in_array
встроенной функции.Это можно продемонстрировать с помощью массива со значениями (10 000 в приведенном ниже тесте), что заставит
in_array
выполнять дополнительный поиск.Он основан на тесте Джейсона, заполняя некоторые случайные значения и иногда находя значение, которое существует в массиве. Все случайно, так что будьте осторожны, времена будут колебаться.
источник
isset()
быстрее.Хотя это должно быть очевидно,
isset()
проверяет только одно значение. Тогда какin_array()
будет перебирать весь массив, проверяя значение каждого элемента.Грубый бенчмаркинг использовать довольно просто
microtime()
.Полученные результаты:
Примечание: результаты были одинаковыми независимо от того, существовали они или нет.
Код:
Дополнительные ресурсы
Я бы посоветовал вам также взглянуть на:
источник
microtime()
других инструментов. Невероятно ценно.in_array
функции по сравнению с использованиемisset
встроенной функции. Было бы лучше с массивом, содержащим кучу случайных ключей и иногда ищущим существующий ключ / значение.while
иforeach
что при каждом обновлении я получал разных «победителей». он всегда зависит от слишком большого количества переменных сервера, и лучше всего перебирать очень большое количество раз в разное время и получать тот, который выигрывает чаще, или просто знать, что происходит в фоновом режиме, и знать, что он будет окончательным победителем несмотря ни на чтоisset()
, что заставляет вас думать, что передача им большего массива сделает это быстрее ?Использование
isset()
использует преимущества более быстрого поиска, поскольку в нем используется хеш-таблица , что исключает необходимостьO(n)
поиска.Ключ сначала хешируется с помощью хеш-функции djb для определения корзины с аналогичным хешированием ключей
O(1)
. Затем ведро просматривается итеративно, пока не будет найден точный ключO(n)
.За исключением преднамеренных конфликтов хэшей , этот подход дает гораздо лучшую производительность, чем
in_array()
.Обратите внимание, что при использовании
isset()
указанным вами способом передача окончательных значений другой функции требует использованияarray_keys()
для создания нового массива. Компромисс памяти может быть достигнут путем хранения данных как в ключах, так и в значениях.Обновить
Хороший способ увидеть, как решения по дизайну кода влияют на производительность во время выполнения, вы можете проверить скомпилированную версию вашего скрипта:
echo isset($arr[123])
echo in_array(123, $arr)
Мало того, что
in_array()
используется относительно неэффективныйO(n)
поиск, его также необходимо вызывать как функцию (DO_FCALL
), тогда как для этогоisset()
используется один код операции (ZEND_ISSET_ISEMPTY_DIM_OBJ
).источник
Второй будет быстрее, так как он ищет только этот конкретный ключ массива и не должен перебирать весь массив, пока он не будет найден (будет смотреть на каждый элемент массива, если он не найден)
источник
isset()
если он не найден?