Разница между циклами
Речь идет о PHP, но я не сомневаюсь, что многие из тех же комментариев будут применимы и к другим языкам.
Проще говоря, каковы различия в различных типах циклов для PHP? Является ли один из них быстрее/лучше других или я должен просто ввести наиболее читаемый цикл?
for ($i = 0; $i < 10; $i++)
{
# code...
}
foreach ($array as $index => $value)
{
# code...
}
do
{
# code...
}
while ($flag == false);
11 answers
Для цикла и в то время как циклы являются циклами условий входа. Сначала они оценивают условие, поэтому блок оператора, связанный с циклом, не будет выполняться даже один раз, если условие не выполняется
Операторы внутри этого блока цикла for будут выполняться 10 раз, значение $i будет от 0 до 9;
for ($i = 0; $i < 10; $i++)
{
# code...
}
То же самое сделано с циклом while:
$i = 0;
while ($i < 10)
{
# code...
$i++
}
Цикл Do-while является циклом условия выхода. Он гарантированно выполняется один раз, затем он оценит условие перед повторением блок
do
{
# code...
}
while ($flag == false);
Foreach используется для доступа к элементам массива от начала до конца. В начале цикла foreach внутренний указатель массива устанавливается на первый элемент массива, на следующем шаге он устанавливается на 2-й элемент массива и так далее, пока массив не закончится. В блоке цикла Значение текущего элемента массива доступно в виде $value, а ключ текущего элемента доступен в виде $index.
foreach ($array as $index => $value)
{
# code...
}
Вы могли бы сделать то же самое с циклом while, например так
while (current($array))
{
$index = key($array); // to get key of the current element
$value = $array[$index]; // to get value of current element
# code ...
next($array); // advance the internal array pointer of $array
}
И, наконец: Руководство по PHP - ваш друг:)
Это CS101, но, поскольку никто другой об этом не упоминал, циклы while оценивают свое состояние перед блоком кода, а циклы do-while оценивают после блока кода, поэтому циклы do-while всегда гарантированно запускают свой блок кода по крайней мере один раз, независимо от условия.
@Брендан:
Статья, которую вы процитировали, серьезно устарела, и информация просто неверна. Особенно последний пункт (используйте for
вместо foreach
) вводит в заблуждение, и обоснование, предлагаемое в статье, больше не применимо к современным версиям.NET.
Хотя верно, что IEnumerator
использует виртуальные вызовы, эти могут на самом деле быть встроены современным компилятором. Кроме того, .NET теперь знает универсальные и строго типизированные перечислители.
Существуют существует множество тестов производительности, которые убедительно доказывают, что for
, как правило, не быстрее, чем foreach
. Вот пример.
Я использую первый цикл при повторении обычного (индексированного?) массива и цикл foreach при работе с ассоциативным массивом. Это просто кажется естественным и помогает коду течь и быть более читабельным, на мой взгляд. Что касается циклов do...while, я использую их, когда мне нужно сделать больше, чем просто пролистать массив.
Однако я не уверен в каких-либо преимуществах производительности.
Производительность в любом случае не намного лучше. В то время как полезно для более сложных задач, чем итерация, но for
и while
функционально эквивалентны.
Foreach
это хорошо, но имеет одно важное предостережение: вы не можете изменять перечисляемый, который вы повторяете. Поэтому не удаляйте, не добавляйте и не заменяйте записи в/в нем. Изменение записей (например, изменение их свойств), конечно, нормально.
С циклом foreach копия исходного массива создается в памяти для использования внутри. Вы не должны использовать их на больших структурах; простой цикл for - лучший выбор. Вы можете более эффективно использовать цикл while для большой неиндексированной структуры, например, такой:
while(list($key, $value) = each($array)) {
Но такой подход особенно уродлив для простой небольшой структуры.
В то время как циклы лучше подходят для циклического прохождения потоков, или как в следующем примере, который вы очень часто видите в PHP:
while ($row = mysql_fetch_array($result)) {
Почти все время различные циклы взаимозаменяемы, и это будет сводиться либо к а) эффективности, либо б) ясности.
Если вы знаете компромиссы в эффективности различных типов циклов, то да, чтобы ответить на ваш первоначальный вопрос: используйте тот, который выглядит наиболее чистым.
Каждая циклическая конструкция служит для разных целей.
Для - Используется для выполнения цикла для определенного количества итераций.
Foreach - используется для перебора всех значений в коллекции.
While - Используется для выполнения цикла до тех пор, пока вы не выполните условие.
Из трех, "в то время как", скорее всего, обеспечит наилучшую производительность в большинстве ситуаций. Конечно, если вы сделаете что-то вроде следующего, вы в основном переписываете цикл "для" (который в c# немного более производителен).
$count = 0;
do
{
...
$count++;
}
while ($count < 10);
Все они имеют разные основные цели, но их также можно использовать примерно одинаково. Это полностью зависит от конкретной проблемы, которую вы пытаетесь решить.
С циклом foreach копия исходного массива создается в памяти для использования внутри.
Foreach хорош, но имеет одно важное предостережение: вы не можете изменять перечисляемое, которое вы повторяете.
И то, и другое не будет проблемой, если вы передадите ссылку вместо значения:
foreach ($array as &$value) {
Я думаю, что это было разрешено с PHP 5.
При доступе к элементам массива для ясности я бы использовал foreach, когда это возможно, и использовал бы только для, если вам нужны фактические значения индекса (например, один и тот же индекс в нескольких массивах). Это также сводит к минимуму вероятность опечаток, так как циклы for делают это слишком простым. В общем, PHP, возможно, не стоит слишком беспокоиться о производительности. И последнее, но не менее важное: для и для каждого есть (или должно быть; я не PHP-er) одно и то же большое время (O(n)), так что вы глядя, возможно, на небольшое увеличение объема используемой памяти или небольшое постоянное или линейное изменение во времени.
Что касается производительности, то для каждого требуется больше времени, чем для