2012-03-15 1 views
0

В некоторой ситуации мы можем использовать , а loop или do-while петля взаимозаменяема. Один из моих друзей сказал мне, что в такой ситуации мы должны использовать do-while loop. Потому что он быстрее, чем , а. Может ли кто-нибудь дать мне доказательство?Какой цикл быстрее в C? while loop или do-while loop

+0

Не было ли этого обсуждения: http: // stackoverflow.com/q/3347001/694576? – alk

+0

, пожалуйста, проверьте сайт для дубликатов перед отправкой –

ответ

6

Оба цикла практически одинаковы (за исключением того факта, что выполнение выполняется хотя бы один раз), и во многих случаях компилируются в соответствии с теми же инструкциями, по крайней мере, на x86.

Следующий код:

int main(int argv, char *argc[]) { 
    int a = 0; 
    while (a < 100) { 
     a++; 
    } 
    a = 0; 
    do { 
     a++; 
    }while(a < 100); 
    return 0; 
} 

Формирует эту сборку (с использованием gcc -S -o temp.as temp.c):

_main: 
    pushl %ebp 
    movl %esp, %ebp 
    andl $-16, %esp 
    subl $16, %esp 
    call ___main 
    movl $0, 12(%esp) >> while 
    jmp L2 
L3: 
    addl $1, 12(%esp) 
L2: 
    cmpl $99, 12(%esp) 
    jle L3 
    movl $0, 12(%esp) >> do-while 
L4: 
    addl $1, 12(%esp) 
    cmpl $99, 12(%esp) 
    jle L4 
    movl $0, %eax 
    leave 
    ret 
+0

Код показывает, что при использовании одной дополнительной команды 'jmp L2'. Даже если это только одна инструкция, мы можем заключить, что do-while быстрее, чем тогда, верно? –

+2

Одна ветка, которая выполняется один раз, не является чем-то, о чем вы должны думать. Это ПУТЬ МУЖСКОЙ МЕНЬШЕ, чтобы считаться медленным фактором. Это происходит только в первый раз. – MByD

+1

И это так незначительные изменения, которые МНОГО МЕНЕЕ важны, чем читаемость кода. – MByD

6

Вы сравниваете яблоки и персики.

A do-while и while Петли различны в зависимости от того, какую функциональность они обеспечивают.
do-while всегда выполняется один раз, while выполняется только в том случае, если условие истинно.

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

+0

@ Просто прочитайте мой вопрос еще раз. Я сказал, что НЕКОТОРЫЕ СИТУАЦИИ мы можем использовать не ВСЕ СИТУАЦИИ. –

+0

@HabeebPerwad: Просто прочитайте мой ответ еще раз. ТРЕТИЙ ПАРАГРАФ является конкретным. –

1

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

2

№. Стандарт C не обеспечивает требования к скорости выполнения, поэтому вообще невозможно доказать.

+0

Существуют очевидные ситуации, которые не будут оптимизированы, например вызовы внешних функций не в библиотеке C (так как они могут иметь побочные эффекты, что-нибудь о). Если ваш охранник цикла является внешним вызовом, тогда, как правило, его вызов будет вдвое дороже, чем вызов его один раз. У нас может быть много правильной интуиции о производительности программы, несмотря на эффект оптимизации. – Kaz

+0

@ Kaz: Я не уверен, что вижу вашу точку зрения. Я согласен с тем, что для некоторых программ и некоторых компиляторов иногда можно прогнозировать производительность; однако это вряд ли представляет собой «доказательство» (как просил ХабибПервад). – Mankarse

2

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

Это микро-оптимизация в лучшем случае.

+0

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

+0

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

1

C семантика описывает поведение абстрактной машины, в которой вопросы оптимизации не имеют значения. (см. стандарт C99, 5.1.2.3p1)

1

Если это ситуация, когда компилятор может ее оптимизировать, придерживайтесь петли while. Тестирование в верхней части цикла более ясное. Причина коренится в формальной проверке. Цикл while проверяет предварительные условия для правильного выполнения тела. Цикл do выполняет тело один раз без тестирования чего-либо, а затем должен иметь дело с последствиями, так сказать. Сложнее рассуждать. Мы должны думать о том, что происходит в результате условий, существовавших до цикла, и эффекта неосторожного выполнения первой итерации.

Если у вас есть защитная петля, которая дорогая (например, вызов какой-либо внешней функции, которая может делать I/O или кто знает, что еще), подумайте о ее перемещении, если это возможно.