для 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
должен быть не вопрос, а то, что делается внутри них для поддержания позиционирования массива.
правильно используется, в то время как является самым быстрым, поскольку он может иметь только одну проверку для каждой итерации, сравнивая один $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;
}