для vs foreach vs while, который быстрее для итерации через массивы в php

какой из них самый быстрый для итерации через массивы в php? или существует другой, который также быстрее для итерации через массивы?

6 ответов


даже если есть какая-то разница, эта разница будет настолько мала, что это не будет иметь никакого значения.

Если у вас есть, скажем, один запрос к базе данных, это займет так много времени по сравнению с циклом итерации по результатам, что вечные дебаты for vs foreach vs while не менять-по крайней мере, если у вас есть достаточное количество данных.

Итак, использовать :

  • все что угодно
  • все, что соответствует вашему программированию стандарт
  • все, что лучше всего подходит для вашего кода / приложения

будет много других вещей, которые вы можете/должны оптимизировать, прежде чем думать о такой микро-оптимизации.


И если вы действительно хотите некоторые цифры (даже если это просто для удовольствия), вы можете сделать тест и увидеть результаты на практике.


для меня я выбираю свой цикл на основе этого:

foreach

использовать при итерации по массиву, длина которого (или может быть) неизвестна.

for

используйте при итерации по массиву, длина которого установлена, или, когда вам нужен счетчик.

while

используйте, когда вы перебираете массив с явной целью поиска или запуска определенного флага.

Теперь это правда, вы можете использовать цикл FOR как цикл FOREACH, используя count($array)... таким образом, в конечном итоге это сводится к вашим личным предпочтениям/стилю.


вообще никакие применимые разницы в скорости между 3 функциями.

чтобы обеспечить контрольные результаты, чтобы продемонстрировать эффективность различных методов, используемых для итерации по массиву из 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 С while и for

$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 продемонстрировал, как это будет использоваться менее эффективно во время итерации.

при функциональной итерации по массиву и сохранение текущей позиции; 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);
}

как вариант 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:Test Results


правильно используется, в то время как является самым быстрым, поскольку он может иметь только одну проверку для каждой итерации, сравнивая один $i с другой переменной $max, и никаких дополнительных вызовов перед циклом (кроме установки $max) или во время цикла (кроме $I++; что по своей сути делается в любом операторе цикла).

когда вы начинаете злоупотреблять им (например, while (list..)) конечно, вам лучше с foreach, так как каждый вызов функции не будет оптимизирован так, как тот, который включен в foreach (потому что это предварительно оптимизирован).

даже тогда array_keys () дает вам то же удобство использования, что и foreach, еще быстрее. И кроме того, если вы находитесь в 2d-массивах, самодельные 2d_array_keys позволят вам использовать в то время как весь путь намного быстрее, чем foreach можно использовать (просто попробуйте сказать следующему foreach в первом foreach, что последний foreach имел в качестве ключей - - -).

кроме того, все вопросы, связанные с первым или последним элементом цикла, используя в то время как($я

и

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";
}

сделать тест тест.

нет большой разницы в производительности, потому что различия расположены внутри логики.

  • вы используете foreach для перебора массива , без целых чисел в качестве ключей.
  • вы используете для для итерации массива с целые числа как ключи.
  • etc.

помните, что предварительная выборка много 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 простым while намного более оптимизирован:

$results = $mysqli->query("SELECT ...");
while( $row = $results->fetch_object() ) {
    echo $row->something;
}