какой из них самый быстрый для итерации через массивы в php? или существует другое, которое также ускоряется для итерации через массивы?
Даже если есть какая-то разница, эта разница будет такой маленькой, что это не имеет значения.
Если у вас есть, скажем, один запрос к базе данных, это займет много времени по сравнению с циклом, повторяющим результаты, которые вечные дебаты for
vs foreach
vs while
не изменят вещь – по крайней мере, если у вас есть разумная количество данных.
Итак, используйте:
Будет много других вещей, которые вы могли бы / должны были бы оптимизировать, прежде чем думать о такой микро-оптимизации.
И если вам действительно нужны некоторые цифры (даже если это просто забавно) , вы можете сделать некоторый бенчмарк и увидеть результаты на практике.
Для меня я выбираю свою петлю на основе этого:
foreach
Используйте при итерации через массив, длина которого (или может быть) неизвестна.
for
Используется при итерации через массив, длина которого задана, или, когда вам нужен счетчик.
while
Используйте, когда вы выполняете итерацию с помощью массива с явной целью поиска или запуска определенного флага.
Теперь это правда, вы можете использовать цикл FOR, как цикл FOREACH, используя count ($ array) … так что в конечном счете это сводится к вашим личным предпочтениям / стилям.
В общем случае не существует соответствующих разностей скорости между тремя функциями.
Чтобы дать результаты тестов, чтобы продемонстрировать эффективность различных методов, используемых для итерации по массиву от 1 to 10,000
.
Результаты тестов разных версий PHP: https://3v4l.org/a3Jn4
while $i++: 0.00077605247497559 sec for $i++: 0.00073003768920898 sec foreach: 0.0004420280456543 sec while current, next: 0.024288892745972 sec while reset, next: 0.012929201126099 sec do while next: 0.011449098587036 sec //added after terminal benchmark while array_shift: 0.36452603340149 sec while array_pop: 0.013902902603149 sec
Принимает во внимание индивидуальные призывы к count
с
$values = range(1, 10000); $l = count($values); $i = 0; while($i<$l){ $i++; } $l = count($values); for($i=0;$i<$l;$i++){ } foreach($values as $val){ }
в$values = range(1, 10000); $l = count($values); $i = 0; while($i<$l){ $i++; } $l = count($values); for($i=0;$i<$l;$i++){ } foreach($values as $val){ }
В приведенных ниже примерах показывается, как он будет использоваться менее эффективно во время итерации.
При функциональном повторении по массиву и поддержании текущей позиции; while
становится намного менее эффективным, так как во время итерации вызывается next()
и current()
.
while($val = current($values)){ next($values); }
Если текущее позиционирование массива не важно, вы можете вызвать reset()
или current()
перед итерацией.
$value = reset($values); while ($value) { $value = next($values); }
do ... while
является альтернативным синтаксисом, который может использоваться, также в сочетании с вызовом reset()
или current()
перед итерацией и перемещением next()
вызова до конца итерации.
$value = current($values); do{ }while($value = next($values));
array_shift
также может быть вызван во время итерации, но это сильно отрицательно влияет на производительность, поскольку array_shift
повторно индексирует массив каждый раз, когда он вызывается.
while($values){ array_shift($values); }
вwhile($values){ array_shift($values); }
В качестве альтернативы array_reverse
можно вызвать до итерации в сочетании с вызовом array_pop
. Это позволит избежать влияния переиндексации при вызове array_shift
.
$values = array_reverse($values); while($values) { array_pop($values); }
В заключение, скорость while
, for
и foreach
не должна быть вопросом, а скорее тем, что делается внутри них для поддержания позиционирования массива.
Терминальные тесты выполняются на PHP 5.6.20 x64 NTS CLI:
Правильно используется, хотя и самый быстрый, поскольку он может иметь только одну проверку для каждой итерации, сравнивая одну переменную $ i с другой переменной $ max и никаких дополнительных вызовов перед циклом (кроме установки $ max) или во время цикла (кроме $ i ++; по сути дела выполняется в любом операторе цикла).
Когда вы начинаете злоупотреблять им (например, в то время как (список ..)), вам лучше с foreach, конечно, так как каждый вызов функции не будет таким же оптимизированным, как тот, который включен в foreach (поскольку этот предварительно оптимизирован).
Даже тогда array_keys () дает вам такую же удобство использования, как foreach, еще быстрее. И кроме того, если вы попали в 2d-массивы, домашние 2d_array_keys позволят вам использовать все время намного быстрее, чем можно использовать foreach (просто попробуйте рассказать следующий foreach в течение первого foreach, что последний foreach имел <2d_array_keys ($ array)> в качестве ключей —).
Кроме того, все вопросы, связанные с первым или последним элементом цикла с использованием while ($ i
А также
while ($people_care_about_optimization!==true){ echo "there still exists a better way of doing it and there's no reason to use any other one"; }
Сделайте контрольный тест.
Не существует существенной «производительности» разницы, потому что различия находятся внутри логики.
Помните, что предварительная выборка большого количества mysqli_result
в удобном массиве может поставить вопрос о том, лучше ли использовать for
/ foreach
/ while
для цикла этого массива, но это неправильный вопрос о плохом решении, которое тратит много ОЗУ.
Поэтому не рекомендуется:
function funny_query_results($query) { $results = $GLOBALS['mysqli']->query($query); $rows = []; while( $row = $results->fetch_object() ) { $rows[] = $results; } return $rows; } $rows = funny_query_results("SELECT ..."); foreach($rows as $row) { // Uh... What should I use? foreach VS for VS while? echo $row->something; }
Прямой способ получить один за другим каждый mysql_result
в простой момент намного оптимизирован:
$results = $mysqli->query("SELECT ..."); while( $row = $results->fetch_object() ) { echo $row->something; }