Разница между циклами


Речь идет о PHP, но я не сомневаюсь, что многие из тех же комментариев будут применимы и к другим языкам.

Проще говоря, каковы различия в различных типах циклов для PHP? Является ли один из них быстрее/лучше других или я должен просто ввести наиболее читаемый цикл?

for ($i = 0; $i < 10; $i++)
{
    # code...
}


foreach ($array as $index => $value)
{
    # code...
}


do
{
    # code...
}
while ($flag == false);
 6
Author: Teifion, 2008-08-22

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 - ваш друг:)

 10
Author: Imran, 2008-08-23 01:44:16

Это CS101, но, поскольку никто другой об этом не упоминал, циклы while оценивают свое состояние перед блоком кода, а циклы do-while оценивают после блока кода, поэтому циклы do-while всегда гарантированно запускают свой блок кода по крайней мере один раз, независимо от условия.

 1
Author: jj33, 2008-08-22 16:46:47
 1
Author: Andy, 2008-08-22 16:48:12

@Брендан:

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

Хотя верно, что IEnumerator использует виртуальные вызовы, эти могут на самом деле быть встроены современным компилятором. Кроме того, .NET теперь знает универсальные и строго типизированные перечислители.

Существуют существует множество тестов производительности, которые убедительно доказывают, что for, как правило, не быстрее, чем foreach. Вот пример.

 1
Author: Konrad Rudolph, 2008-08-22 17:52:33

Я использую первый цикл при повторении обычного (индексированного?) массива и цикл foreach при работе с ассоциативным массивом. Это просто кажется естественным и помогает коду течь и быть более читабельным, на мой взгляд. Что касается циклов do...while, я использую их, когда мне нужно сделать больше, чем просто пролистать массив.

Однако я не уверен в каких-либо преимуществах производительности.

 0
Author: Thomas Owens, 2008-08-22 16:34:58

Производительность в любом случае не намного лучше. В то время как полезно для более сложных задач, чем итерация, но for и while функционально эквивалентны.

Foreach это хорошо, но имеет одно важное предостережение: вы не можете изменять перечисляемый, который вы повторяете. Поэтому не удаляйте, не добавляйте и не заменяйте записи в/в нем. Изменение записей (например, изменение их свойств), конечно, нормально.

 0
Author: wvdschel, 2008-08-22 16:37:42

С циклом foreach копия исходного массива создается в памяти для использования внутри. Вы не должны использовать их на больших структурах; простой цикл for - лучший выбор. Вы можете более эффективно использовать цикл while для большой неиндексированной структуры, например, такой:

while(list($key, $value) = each($array)) {

Но такой подход особенно уродлив для простой небольшой структуры.

В то время как циклы лучше подходят для циклического прохождения потоков, или как в следующем примере, который вы очень часто видите в PHP:

while ($row = mysql_fetch_array($result)) {

Почти все время различные циклы взаимозаменяемы, и это будет сводиться либо к а) эффективности, либо б) ясности.

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

 0
Author: mercutio, 2008-08-22 16:37:44

Каждая циклическая конструкция служит для разных целей.

Для - Используется для выполнения цикла для определенного количества итераций.

Foreach - используется для перебора всех значений в коллекции.

While - Используется для выполнения цикла до тех пор, пока вы не выполните условие.

Из трех, "в то время как", скорее всего, обеспечит наилучшую производительность в большинстве ситуаций. Конечно, если вы сделаете что-то вроде следующего, вы в основном переписываете цикл "для" (который в c# немного более производителен).

$count = 0;
do
{
   ...
   $count++;
}
while ($count < 10);  

Все они имеют разные основные цели, но их также можно использовать примерно одинаково. Это полностью зависит от конкретной проблемы, которую вы пытаетесь решить.

 0
Author: JeremiahClark, 2008-08-22 17:39:03

С циклом foreach копия исходного массива создается в памяти для использования внутри.

Foreach хорош, но имеет одно важное предостережение: вы не можете изменять перечисляемое, которое вы повторяете.

И то, и другое не будет проблемой, если вы передадите ссылку вместо значения:

 foreach ($array as &$value) {

Я думаю, что это было разрешено с PHP 5.

 0
Author: Jeremy Ruten, 2008-08-22 23:30:52

При доступе к элементам массива для ясности я бы использовал foreach, когда это возможно, и использовал бы только для, если вам нужны фактические значения индекса (например, один и тот же индекс в нескольких массивах). Это также сводит к минимуму вероятность опечаток, так как циклы for делают это слишком простым. В общем, PHP, возможно, не стоит слишком беспокоиться о производительности. И последнее, но не менее важное: для и для каждого есть (или должно быть; я не PHP-er) одно и то же большое время (O(n)), так что вы глядя, возможно, на небольшое увеличение объема используемой памяти или небольшое постоянное или линейное изменение во времени.

 0
Author: Jared Updike, 2008-08-22 23:47:01

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

Http://forums.asp.net/p/1041090/1457897.aspx

 0
Author: juan, 2013-01-24 13:09:59