Для цикла против цикла - PullRequest
       28

Для цикла против цикла

1 голос
/ 17 февраля 2012

В моей лекции по дизайну и анализу Алгоритмы, которые инструктор сказал, что цикл for займет меньше времени, чем цикл while для следующего примера алгоритма.

1.  for(int i=0;i<5;i++)
    {    
2.      print(i);    
    }

1.  int i=0;
2.  while(i<5)
    {    
3.      print(i);    
4.      i++;    
    }

Он сказал, что компилятор будет читать 1. в течение 5 раз строку 2. 4 раза, таким образом, общее время 5 + 4 = 9 Но в случае цикла while. Компилятор прочитает 1. 1 раз, 2. на 5 раз, 3 на 4 раза и 4. на 4 раза. Таким образом общее время 1 + 5 + 4 + 4 = 14 раз Пожалуйста, скажите мне, это правильно. Цикл for быстрее, чем цикл while?

Спасибо.

Ответы [ 3 ]

6 голосов
/ 17 февраля 2012

По крайней мере для MSVC 16 (VS 2010) код в обоих случаях практически одинаков:

для

; Line 5
    xor esi, esi
$LL3@main:
; Line 6
    push    esi
    push    OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
    call    _printf
    inc esi
    add esp, 8
    cmp esi, 5
    jl  SHORT $LL3@main

, в то время как

; Line 4
    xor esi, esi
$LL2@main:
; Line 6
    push    esi
    push    OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
    call    _printf
; Line 7
    inc esi
    add esp, 8
    cmp esi, 5
    jl  SHORT $LL2@main

Код в моем хранилище Subversion .

2 голосов
/ 17 февраля 2012

Я передам производительность (подсказка: нет разницы, проверьте сгенерированный IR или сборку для доказательства), однако есть два важных различия в синтаксисе и обслуживании .

Синтаксис

Область действия переменной i отличается. В случае for, i доступен только в заголовках for и body , тогда как в случае while он доступен после цикла. Как правило, лучше иметь более узкие рамки, меньше переменных в полете означает меньше контекста, о котором нужно беспокоиться при кодировании.

Техническое обслуживание

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

Кроме того, при введении операторов continue есть одно важное отличие:

for(int i = 0; i != 10; ++i) {
  if (array[i] == nullptr) { continue; }
  // act on it
}


int i = 0;
while (i != 10) {
  if (array[i] == nullptr) { continue; }
  // act on it
  ++i;
}

В случае while введение continue создало ошибку: бесконечный цикл, так как счетчик больше не реализован.

Impact

for циклы более удобочитаемы и лучше подходят для регулярных шаблонов итераций. Еще лучше, в C ++ 11 утверждение диапазона для:

for (Item const& item : collection) {
}

, где итерация полностью заботится компилятором, так что вы не ошибетесь! (это делает алгоритм for_each несколько спорным ... и мы можем пожелать, чтобы старшее для формы начало отступать)

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

2 голосов
/ 17 февраля 2012

Во всех современных компиляторах анализ цикла выполняется на промежуточном представлении более низкого уровня (т. Е. Когда все конструкции цикла высокого уровня раскрываются в метки и переходы).Для компилятора оба цикла абсолютно эквивалентны.

...