“Для (; ;)” быстрее, чем, “в то время как (TRUE)”? В противном случае, почему люди используют его?

for (;;) {
    //Something to be done repeatedly
}

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

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

Да ведь и это действительно стоит того? Если так, почему не только определяют его этот путь:

#define while(true) for(;;)

См. также: Который быстрее: в то время как (1) или в то время как (2)?

160
задан Community 23 May 2017 в 12:18
поделиться

16 ответов

  1. Это не быстрее.
  2. Если вам действительно интересно, скомпилируйте вывод на ассемблере для вашей платформы и посмотрите.
  3. Это не имеет значения. Это не имеет значения. Пишите свои бесконечные циклы, как хотите.
259
ответ дан 23 November 2019 в 21:27
поделиться

Я предполагаю, что while (true) более читабельно, чем for (;;) - похоже, что программист что-то упустил в цикле for :)

и кого волнует, какой из них быстрее

2
ответ дан 23 November 2019 в 21:27
поделиться

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

Однако я предлагаю вам предпочесть для (;;) по следующим причинам:

  • ряд компиляторов, которые я использовал, будут генерировать предупреждение о постоянном выражении для while (true) с соответствующими настройками уровня предупреждения .

  • в вашем примере макрос TRUE может быть определен не так, как вы ожидаете

  • существует много возможных вариантов бесконечного цикла while, например while (1) , while (true) , в то время как (1 == 1) и т.д .; поэтому для (;;) , вероятно, приведет к большей согласованности.

5
ответ дан 23 November 2019 в 21:27
поделиться

Это определенно не быстрее ни в одном нормальном компиляторе. Оба они будут объединены в безусловные прыжки. Версию for легче набирать (как сказал Нил), и она будет понятна, если вы понимаете синтаксис цикла 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
46
ответ дан 23 November 2019 в 21:27
поделиться

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

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

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

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

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

172
ответ дан 23 November 2019 в 21:27
поделиться

Благодаря Деннису Ричи

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

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

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

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

49
ответ дан 23 November 2019 в 21:27
поделиться

Цикл «навсегда» популярен во встроенных системах в качестве фонового цикла.Некоторые люди реализуют это как:

for (; ;)
{
 // Stuff done in background loop
}

А иногда это реализуется как:

while (TRUE /* or use 1 */)
{
 // Stuff done in background loop
}

И еще одна реализация:

do
{
 // Stuff done in background loop
} while (1 /* or TRUE */);

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

4
ответ дан 23 November 2019 в 21:27
поделиться
while(true)

генерирует предупреждение в Visual Studio (условие постоянно). В большинстве мест, где я работал, производственные сборки с предупреждениями компилируются как ошибки. Поэтому

for(;;)

предпочтительнее.

11
ответ дан 23 November 2019 в 21:27
поделиться

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

#define EVER ;;

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

for (EVER)
{
    /* blah */
}
17
ответ дан 23 November 2019 в 21:27
поделиться

Не просто известный шаблон, а стандартная идиома в C (и C++)

11
ответ дан 23 November 2019 в 21:27
поделиться

Какой из способов быстрее - это вопрос личных предпочтений. Лично я наборщик текста и никогда не смотрю на клавиатуру во время программирования - я могу набрать все 104 клавиши на клавиатуре.

Я считаю, что быстрее набирать "while (TRUE)".

Я мысленно добавил несколько измерений движения пальцев и просуммировал их. "for (;;)" имеет примерно 12 клавиш перемещения назад и четвертое (между клавишами Home и клавишами, а также между клавишами Home и клавиша SHIFT) «while (TRUE)» имеет примерно 14 клавиш для перемещений назад и на четвертую позицию.

Однако я гораздо менее подвержен ошибкам при вводе последнего. Я мысленно думаю словами за раз, поэтому я нахожу, что быстрее набирать такие вещи, как «nIndex», чем акронимы, такие как «nIdx», потому что на самом деле мне приходится мысленно произносить буквы, а не произносить их в уме и позволять пальцам автоматически -введите слово (например, езда на велосипеде)

(My TypingTest.com benchmark = 136 WPM)

9
ответ дан 23 November 2019 в 21:27
поделиться

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

56
ответ дан 23 November 2019 в 21:27
поделиться

Нет никакой разницы в смысле генерируемого машинного кода.

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

12
ответ дан 23 November 2019 в 21:27
поделиться

Все хорошие ответы - поведение должно быть точно таким же.

ОДНАКО - Просто предположим, что это имело значение. Предположим, на одну итерацию приходилось еще 3 инструкции.

Стоит ли вам заботиться?

ТОЛЬКО если то, что вы делаете внутри цикла, почти ничего , что почти никогда не имеет значения.

Я хочу сказать, что есть микрооптимизация и макрооптимизация. Микрооптимизация похожа на «стрижку, чтобы похудеть».

6
ответ дан 23 November 2019 в 21:27
поделиться

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

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

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

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

21
ответ дан 23 November 2019 в 21:27
поделиться

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

start:
/* BLAH */
goto start;
16
ответ дан 23 November 2019 в 21:27
поделиться