Является ли "for (;;)" быстрее, чем "while (TRUE)"? Если нет, то почему люди используют это? - PullRequest
156 голосов
/ 10 апреля 2010
for (;;) {
    //Something to be done repeatedly
}

Я видел, что подобные вещи часто используются, но я думаю, что это довольно странно ... Разве не было бы намного яснее сказать while(true) или что-то в этом роде?

Я предполагаю, что (как причина, по которой многие программисты прибегают к загадочному коду), это крошечный запас быстрее?

Почему, и действительно ли это действительно стоит? Если так, то почему бы просто не определить это так:

#define while(true) for(;;)

См. Также: Что быстрее: while (1) или while (2)?

Ответы [ 20 ]

252 голосов
/ 10 апреля 2010
  1. Это не быстрее.
  2. Если вам действительно все равно, скомпилируйте выходные данные на ассемблере для вашей платформы и посмотрите.
  3. Это не имеет значения. Это никогда не имеет значения. Напишите свои бесконечные циклы так, как вам нравится.
165 голосов
/ 10 апреля 2010

Я предпочитаю for(;;) по двум причинам.

Одна из них заключается в том, что некоторые компиляторы выдают предупреждения на while(true) (что-то вроде «условие цикла константа»). Избегать предупреждений всегда полезно.

Другое - я думаю, что for(;;) понятнее и понятнее. Я хочу бесконечный цикл. Буквально не имеет никаких условий, это ни от чего не зависит. Я просто хочу, чтобы это продолжалось вечно, пока я не сделаю что-то, чтобы вырваться из этого.

Принимая во внимание, что с while(true), хорошо, что правда имеет отношение к чему-либо? Я не заинтересован в цикле, пока истина не станет ложной, что буквально говорит эта форма (цикл, пока истина - истина). Я просто хочу зациклить.

И нет, разницы в производительности нет абсолютно.

55 голосов
/ 10 апреля 2010

Лично я использую for (;;), потому что в нем нет цифр, это просто ключевое слово. Я предпочитаю это while (true), while (1), while (42), while (!0) и т. Д. И т. Д.

48 голосов
/ 10 апреля 2010

Из-за Денниса Ритчи

  • Я начал использовать for (;;), потому что именно так Деннис Ритчи делает это в K & R, и при изучении нового языка я всегда стараюсь подражать умным парням.

  • Это идиоматический C / C ++. Вероятно, в конечном итоге лучше привыкнуть к этому, если вы планируете многое делать в пространстве C / C ++.

  • Ваш #define не будет работать, так как объект # define'd должен выглядеть как идентификатор C.

  • Все современные компиляторы генерируют одинаковый код для двух конструкций.

46 голосов
/ 10 апреля 2010

Конечно, это не быстрее любого здравомыслящего компилятора. Они оба будут скомпилированы в безусловные переходы. Версия for легче набрать (как сказал Нейл) и будет понятна, если вы понимаете синтаксис цикла.

Если вам интересно, вот что дает мне gcc 4.4.1 для x86. Оба используют инструкцию x86 JMP .

void while_infinite()
{
    while(1)
    {
    puts("while");
    }
}

void for_infinite()
{
    for(;;)
    {
    puts("for");
    }
}

компилируется в (частично):

.LC0:
.string "while"
.text
.globl while_infinite
    .type   while_infinite, @function
while_infinite:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
.L2:
    movl    $.LC0, (%esp)
    call    puts
    jmp .L2
    .size   while_infinite, .-while_infinite
    .section    .rodata
.LC1:
    .string "for"
    .text
.globl for_infinite
    .type   for_infinite, @function
for_infinite:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
.L5:
    movl    $.LC1, (%esp)
    call    puts
    jmp .L5
    .size   for_infinite, .-for_infinite
41 голосов
/ 27 августа 2012

Я предпочитаю for (;;), потому что он наиболее согласован в разных C-подобных языках.

В C ++ while (true) нормально, но в C вы используете заголовок для определения true, но TRUE также является часто используемым макросом. Если вы используете while (1), то это правильно в C и C ++ и JavaScript, но не в Java или C #, которые требуют, чтобы условие цикла было логическим, например while (true) или while (1 == 1). В PHP ключевые слова нечувствительны к регистру, но язык предпочитает заглавные буквы TRUE.

Однако for (;;) всегда полностью корректен во всех этих языках.

21 голосов
/ 10 апреля 2010

Я лично предпочитаю идиому for (;;) (которая будет компилироваться в тот же код, что и while (TRUE).

Использование while (TRUE) может быть более читабельным в некотором смысле, я решил использовать идиому for (;;), потому что выделяется .

Конструкция бесконечного цикла должна быть легко замечена или вызвана в коде, и я лично считаю, что стиль for (;;) делает это немного лучше, чем while (TRUE) или while (1).

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

17 голосов
/ 10 апреля 2010

Я видел, что некоторые люди предпочитают это, потому что у них есть #define где-то так:

#define EVER ;;

Что позволяет им написать это:

for (EVER)
{
    /* blah */
}
16 голосов
/ 10 апреля 2010

Как насчет (если ваш язык поддерживает это):

start:
/* BLAH */
goto start;
12 голосов
/ 10 апреля 2010

Нет разницы с точки зрения генерируемого машинного кода.

Тем не менее, просто чтобы уловить тенденцию, я бы сказал, что форма while (TRUE) гораздо более читабельна и интуитивно понятна, чем для (;;), и что читаемость и ясность являются гораздо более важными причинами для руководящих принципов кодирования, чем для любых других. причины, которые я услышал для подхода for (;;) (я предпочитаю основывать свои руководящие принципы кодирования на здравом рассуждении и / или доказательстве эффективности самостоятельно).

...