Речь идет о PHP, но я не сомневаюсь, что многие из тех же комментариев будут применяться к другим языкам.
Проще говоря, каковы различия в разных типах циклов для PHP? Является ли это быстрее / лучше других или просто нужно вставить наиболее читаемый цикл?
for ($i = 0; $i < 10; $i++) { # code... } foreach ($array as $index => $value) { # code... } do { # code... } while ($flag == false);
Для циклов и циклов While петли ввода. Сначала они оценивают условие, поэтому блок операторов, связанный с циклом, не будет выполняться даже один раз, если условие не выполняется
Операторы внутри этого цикла цикла будут выполняться 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, но поскольку никто не упомянул об этом, в то время как циклы оценивают их состояние перед блоком кода и делают-пока оценивают после блока кода, так что циклы do-while всегда гарантируют выполнение своего кодового блока хотя бы один раз, независимо от состояния.
PHP-тесты
@brendan:
Статья, которую вы цитировали, серьезно устарела, и информация просто неверна. Особенно последний пункт (использование вместо foreach
) вводит в заблуждение, и оправдание, предлагаемое в статье, больше не относится к современным версиям .NET.
Хотя верно, что IEnumerator
использует виртуальные вызовы, они могут быть встроены в современный компилятор. Кроме того, .NET теперь знает дженерики и строго типизированные счетчики.
Есть много тестов производительности, которые доказывают окончательно, что, как правило, не быстрее, чем foreach
. Вот пример .
Я использую первый цикл при итерации по сравнению с обычным (индексированным?) Массивом и циклом foreach при работе с ассоциативным массивом. Это кажется естественным, и, по моему мнению, помогает кодовому потоку и быть более читаемым. Что касается do … while, я использую те, когда мне приходится делать больше, чем просто пролистывать массив.
Однако я не уверен в каких-либо преимуществах в производительности.
В обоих случаях производительность не намного лучше. Хотя это полезно для более сложных задач, чем повторение, но for
и в while
как функционально эквивалентны.
Foreach
хорошо, но имеет одно важное предостережение: вы не можете изменить перечислимый вами итерационный процесс. Поэтому нет удаления, добавления или замены записей в / в нем. Разумеется, изменение записей (например, изменение их свойств) в порядке.
С циклом foreach копия исходного массива создается в памяти для использования внутри. Вы не должны использовать их на больших структурах; простой цикл – лучший выбор. Вы можете использовать цикл while более эффективно для большой неиндексированной структуры, например:
while(list($key, $value) = each($array)) {
Но этот подход особенно уродлив для простой небольшой структуры.
в то время как петли лучше подходят для циклических потоков, или как в следующем примере, который вы часто видите в PHP:
while ($row = mysql_fetch_array($result)) {
Почти все время различные петли взаимозаменяемы, и это сводится к: a) эффективности или б) ясности.
Если вы знаете эффективность компромиссов разных типов циклов, то да, чтобы ответить на ваш первоначальный вопрос: используйте тот, который выглядит наиболее чистым.
Каждая конструкция цикла имеет другую цель.
for – Это используется для цикла для определенного количества итераций.
foreach – используется для циклического преобразования всех значений в коллекции.
while – Это используется для цикла, пока вы не встретите условие.
Из трех, «пока», скорее всего, обеспечит лучшую производительность в большинстве ситуаций. Конечно, если вы делаете что-то вроде следующего, вы в основном переписываете цикл «for» (который в c # немного более эффективен).
$count = 0; do { ... $count++; } while ($count < 10);
Все они имеют разные основные цели, но их также можно использовать примерно так же. Это полностью зависит от конкретной проблемы, которую вы пытаетесь решить.
С циклом foreach копия исходного массива создается в памяти для использования внутри.
Foreach хорошо, но имеет одно важное предостережение: вы не можете изменить перечислимый вами итерационный процесс.
Обе эти проблемы не будут проблемой, если вы передадите ссылку вместо значения:
foreach ($array as &$value) {
Я думаю, что это было разрешено с PHP 5.
При доступе к элементам массива для ясности я использую foreach, когда это возможно, и использую только для if, если вам нужны фактические значения индекса (например, один и тот же индекс в нескольких массивах). Это также минимизирует вероятность ошибок типографии, поскольку для циклов это слишком легко. В общем, PHP, возможно, не слишком сильно беспокоится о производительности. И последнее, но не менее важное: for и foreach имеют (или должны иметь, я не PHP-er) одно и то же время Big-O (O (n)), поэтому вы, возможно, смотрите на небольшое количество использования памяти или небольшое постоянное или линейное попадание во времени.
Что касается производительности, foreach больше потребляет, чем for