Какой цикл быстрее for или while
Перейти к содержимому

Какой цикл быстрее for или while

Что быстрее while (true) или for (;;)?

В сырцах разных авторов видел я разные варианты вечного цикла. Чаще всего мне встречались следующие:

Поскольку каждый защищал “свой вечный цикл” как родного, я решил разобраться. Кто же пишет более оптимальный код.

Я написал 2 исходника:

И дезассемблировал. Кому лень читать ассемблерные листниги — можете прокрутить страницу вниз. Собственно листинги:

Разбираем на пальцах

Различные оптимизации не повлияли на реализацию цикла while (true) — он всегда выполнял 3 команды: mov, callq и jmp. Так же оптимизации не повлияли на реализацию for — он тоже всегда был из 3х команд: mov, callq, jmp. Между собой mov, callq и jmp ничем не отличались. Длинна команд в байтах во всех 6и случаях неизменна.

Есть только небольшая разница между реализациями -O1 и -O2/-O3 jmp выполнялся на main+4 а не на main+8, но с учетом того, что это статичный адрес (как видно из asm-кода) оно тоже не несет разницы в производительности… Хотя… а вдруг страницы памяти разные, ведь на сколько я знаю для телодвижений между разными страницами памяти в x86 (и amd64) требуются дополнительные усилия проца!

Узнаем:
400438/4096 = 97,763183594
400520/4096 = 97,783203125

Пронесло. Страница памяти одна. Да это 97 страница Виртуальной памяти Виртуального адресного пространства процесса. Но именно она нам и нужна.

while (true) и for (;;) идентичны по производительности между собой и с любыми оптимизациями -Ox. Так что если Вас спросят кто из них быстрее — смело говорите что “for (;;)” — 8 символов написать быстрее, чем “while (true)” — 12 символов.

Цикл for

Цикл while можно использовать во всех случаях, когда команду или группу команд нужно выполнить несколько раз. Но из всех случаев один случай стоит выделить особо.

Это случай, когда программист (автор программы) заранее знает, сколько раз должен выполниться его цикл. Обычно это решается введением специальной переменной-счетчика, и каждую итерацию цикла переменная увеличивается (или уменьшается) на 1 .

Вроде бы все работает как надо, но не очень удобно. Перед циклом мы задаем стартовое значение переменной-счетчика, затем в условии проверяем, не достигла ли она уже финального значения. А вот меняем ее обычно в самом конце тела цикла.

А если тело цикла большое? Или у нас несколько вложенных циклов? В общем, хотелось бы в таких случаях собрать всю эту информацию о переменной-счетчике в одном месте. Так в Java появился цикл for . Выглядит он тоже не очень сложно:

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

Все на самом деле проще, чем кажется: компилятор превращает цикл for в обычный цикл while таким образом:

Или лучше продемонстрируем на примере: два примера ниже идентичны.

Вариант 1 Вариант 2

Мы просто взяли и собрали в одном месте весь код, который касается переменной-счетчика — i .

команда1 в цикле for выполняется только один раз перед самим циклом (это видно на втором примере)

команда2 выполняется столько же раз, сколько и тело цикла, но будет выполняться каждый раз уже после того, как выполнится все тело цикла

2. Где используется цикл for

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

Цикл while Цикл for

Обратите внимание на последний пример. Там пропущены команды работы со счетчиком цикла. Нет счетчика — нет команд.

Java разрешает не писать в цикле for «команду по инициализации счетчика» и «команду по изменению счетчика». И даже выражение-условие цикла можно не писать.

Which loop is faster, while or for?

You can get the same output with for and while loops:

While:

For:

But which one is faster?

user avatar

17 Answers 17

That clearly depends on the particular implementation of the interpreter/compiler of the specific language.

That said, theoretically, any sane implementation is likely to be able to implement one in terms of the other if it was faster so the difference should be negligible at most.

Of course, I assumed while and for behave as they do in C and similar languages. You could create a language with completely different semantics for while and for

user avatar

In C#, the For loop is slightly faster.

For loop average about 2.95 to 3.02 ms.

The While loop averaged about 3.05 to 3.37 ms.

Quick little console app to prove:

user avatar

I find the fastest loop is a reverse while loop, e.g:

user avatar

As others have said, any compiler worth its salt will generate practically identical code. Any difference in performance is negligible — you are micro-optimizing.

The real question is, what is more readable? And that’s the for loop (at least IMHO).

If that were a C program, I would say neither. The compiler will output exactly the same code. Since it’s not, I say measure it. Really though, it’s not about which loop construct is faster, since that’s a miniscule amount of time savings. It’s about which loop construct is easier to maintain. In the case you showed, a for loop is more appropriate because it’s what other programmers (including future you, hopefully) will expect to see there.

I used a for and while loop on a solid test machine (no non-standard 3rd party background processes running). I ran a for loop vs while loop as it relates to changing the style property of 10,000 <button> nodes.

The test is was run consecutively 10 times, with 1 run timed out for 1500 milliseconds before execution:

Here is the very simple javascript I made for this purpose

Here are the results I got

Update

A separate test I have conducted is located below, which implements 2 differently written factorial algorithms, 1 using a for loop, the other using a while loop.

Here is the code:

And the results for the factorial benchmark:

Conclusion: No matter the sample size or specific task type tested, there is no clear winner in terms of performance between a while and for loop. Testing done on a MacAir with OS X Mavericks on Chrome evergreen.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *