Разница между петлями - PullRequest
       59

Разница между петлями

6 голосов
/ 22 августа 2008

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

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

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


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


do
{
    # code...
}
while ($flag == false);

Ответы [ 11 ]

10 голосов
/ 23 августа 2008

Для циклов и циклов while являются циклами входных условий. Сначала они оценивают условие, поэтому блок операторов, связанный с циклом, не будет запущен ни разу, если условие не выполнено

Операторы внутри этого блока 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 - ваш друг:)

1 голос
/ 22 августа 2008

@ Брендан:

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

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

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

1 голос
/ 22 августа 2008
1 голос
/ 22 августа 2008

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

0 голосов
/ 23 августа 2008

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

0 голосов
/ 23 августа 2008

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

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

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

 foreach ($array as &$value) {

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

0 голосов
/ 22 августа 2008

Каждая циклическая конструкция имеет свое назначение.

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

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

while - используется для зацикливания, пока не будет выполнено условие.

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

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

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

0 голосов
/ 22 августа 2008

В отношении производительности, foreach является более потребляющим, чем для

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

0 голосов
/ 22 августа 2008

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

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

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

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

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

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

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

0 голосов
/ 22 августа 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...