Es "for(;;)" más rápido que "while (TRUE)"? Si no, ¿por qué la gente lo usa?


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

He visto que este tipo de cosas se usan mucho, pero creo que es bastante extraño... ¿No sería mucho más claro decir while(true), o algo por el estilo?

Supongo que (como es la razón por la que muchos programadores recurren al código críptico) este es un pequeño margen más rápido?

¿Por qué, y es realmente vale la pena? Si es así, ¿por qué no definirlo de esta manera:

#define while(true) for(;;)

Ver también: ¿Cuál es más rápido: while(1) o while(2)?

Author: Community, 2010-04-10

20 answers

  1. No es más rápido.
  2. Si realmente le importa, compile con la salida del ensamblador para su plataforma y mire para ver.
  3. no importa. Esto nunca importa. Escribe tus bucles infinitos como quieras.
 244
Author: Ben Zotto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 22:06:49

Prefiero for(;;) por dos razones.

Uno es que algunos compiladores producen advertencias en while(true) (algo así como "la condición del bucle es constante"). Evitar las advertencias siempre es algo bueno que hacer.

Otra es que creo que for(;;) es más claro y más revelador. Quiero un bucle infinito. Literalmente no tiene ninguna condición, no depende de nada. Sólo quiero que continúe para siempre, hasta que haga algo para salir de ella.

Mientras que con while(true), bueno, lo que es cierto tiene que ver con ¿algo? No estoy interesado en el bucle hasta que verdadero se convierta en falso, que es lo que esta forma literalmente dice (bucle mientras que verdadero es verdadero). Sólo quiero hacer un bucle.

Y no, no hay absolutamente ninguna diferencia de rendimiento.

 163
Author: jalf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-07 14:52:31

Personalmente uso for (;;) porque no hay ningún número en él, es solo una palabra clave. Yo prefiero que while (true), while (1), while (42), while (!0) etc etc.

 52
Author: ta.speot.is,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 22:10:39

Por Dennis Ritchie

  • Comencé a usar for (;;) porque esa es la forma en que Dennis Ritchie lo hace en K&R, y cuando aprendo un nuevo idioma siempre trato de imitar a los chicos inteligentes.

  • Esto es C/C++idiomático. Probablemente sea mejor a largo plazo acostumbrarse a él si planea hacer mucho en el espacio de C/C++.

  • Su #define no funcionará, ya que la cosa #definid'd tiene que parecerse a un identificador C.

  • Todos los compiladores modernos generarán el mismo código para las dos construcciones.

 47
Author: Mark Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-10 06:44:55

Ciertamente no es más rápido en ningún compilador cuerdo. Ambos serán compilados en saltos incondicionales. La versión for es más fácil de escribir (como dijo Neil) y será clara si entiendes la sintaxis de bucle for.

Si tienes curiosidad, esto es lo que gcc 4.4.1 me da para x86. Ambos usan la instrucción x86 JMP.

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

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

Compila (en parte):

.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
 45
Author: Matthew Flaschen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-12 13:06:05

Prefiero for (;;) porque es el más consistente en diferentes lenguajes similares a C.

En C++ while (true) está bien, pero en C depende de un encabezado para definir true, pero TRUE también es una macro de uso común. Si usas while (1) es correcto en C y C++, y JavaScript, pero no Java o C#, que requieren que la condición de bucle sea booleana, como while (true) o while (1 == 1). En PHP, las palabras clave no distinguen entre mayúsculas y minúsculas, pero el lenguaje prefiere las mayúsculas TRUE.

Sin Embargo, for (;;) es siempre completamente correcto en todos esos idiomas.

 40
Author: Boann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-23 10:54:14

Personalmente prefiero el modismo for (;;) (que compilará el mismo código que while (TRUE).

Usar while (TRUE) puede ser más legible en un sentido, he decidido usar el modismo for (;;)porque se destaca.

Una construcción de bucle infinito debe ser fácilmente notada o llamada en código, y personalmente creo que el estilo for (;;) hace esto un poco mejor que while (TRUE) o while (1).

También, recuerdo que algunos compiladores emiten advertencias cuando la expresión de control de un bucle while es una constante. No creo que eso suceda demasiado, pero solo el potencial de advertencias falsas es suficiente para que quiera evitarlo.

 21
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 23:16:09

He visto que algunas personas lo prefieren porque tienen un #define en algún lugar como este:

#define EVER ;;

Que les permite escribir esto:

for (EVER)
{
    /* blah */
}
 17
Author: rmeador,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 22:30:07

Qué pasa (si su idioma lo soporta):

start:
/* BLAH */
goto start;
 16
Author: bungle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 23:17:04

No hay diferencia en términos del código máquina que se genera.

Sin embargo, solo para contrarrestar la tendencia, argumentaría que la forma while(TRUE) es mucho más legible e intuitiva que for(;;), y que la legibilidad y la claridad son razones mucho más importantes para las directrices de codificación que cualquier otra razón que haya escuchado para el enfoque for (;;) (Prefiero basar mis directrices de codificación en un razonamiento sólido y/o una prueba de efectividad).

 12
Author: Jason Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 22:18:05

No solo un patrón bien conocido, sino un modismo estándar en C (y C++)

 11
Author: James McLeod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 22:09:54
while(true)

Genera una advertencia con Visual Studio (la condición es constante). La mayoría de los lugares en los que he trabajado compilan compilaciones de producción con advertencias como errores. So

for(;;)
Se prefiere

.

 11
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-10 05:49:41

Ambos deberían ser iguales si su código está optimizado por el compilador. Para explicar lo que quiero decir con optimización, aquí hay un código de ejemplo escrito en MSVC 10:

int x = 0;

while(true) // for(;;)
{
    x +=1;

    printf("%d", x);
}

Si lo compila en modo de depuración (sin ninguna optimización (/Od)) el desmontaje muestra la clara diferencia. Hay instrucciones adicionales para la condición true dentro de while.

while(true)
00D313A5  mov         eax,1                //extra 
00D313AA  test        eax,eax              //extra
00D313AC  je          main+39h (0D313B9h)  //extra
    {
        x +=1;
00D313AE  mov         eax,dword ptr [x]  
00D313B1  add         eax,1  
00D313B4  mov         dword ptr [x],eax  
    printf("%d", x);
    ...
    }
00D313B7  jmp         main+25h (0D313A5h)  


for(;;)
    {
        x +=1;
00D213A5  mov         eax,dword ptr [x]  
00D213A8  add         eax,1  
00D213AB  mov         dword ptr [x],eax  
    printf("%d", x);
    ...
    }
00D213AE  jmp         main+25h (0D213A5h)  

Sin embargo, si construye su código en modo Release (con el valor predeterminado Maximize Speed (/O2)), obtendrá la misma salida para ambos. Ambos bucles se reducen a una instrucción de salto.

for(;;)
    {
        x +=1;
01291010  inc         esi  

        printf("%d", x);
    ...
    }
0129101C  jmp         main+10h (1291010h)  

    while(true)
    {
        x +=1;
00311010  inc         esi  

        printf("%d", x);
    ...
    }
0031101C  jmp         main+10h (311010h)  

Lo que se va a utilizar no importa para un compilador decente con optimización de velocidad está activado.

 10
Author: SylvanBlack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-02 07:39:48

Es una cuestión de preferencia personal qué camino es más rápido. Personalmente, soy un touchtypist y nunca miro mi teclado, durante la programación can puedo touchtype las 104 teclas de mi teclado.

Encuentro si es más rápido escribir "while (TRUE)".

Mentalmente agregué algunas medidas de movimiento de los dedos y las totalicé. "for (;;)" tiene alrededor de 12 teclas-anchos de movimientos hacia atrás y hacia la cuarta (entre las teclas de inicio y las teclas, y entre las teclas de inicio y la tecla MAYÚS) "while (TRUE)" tiene alrededor de 14 clave-anchos de los movimientos hacia atrás y hacia el cuarto.

Sin embargo, soy mucho menos propenso a errores al escribir este último. Mentalmente pienso en palabras a la vez, por lo que encuentro más rápido escribir cosas como "nIndex" que acrónimos como "nIdx" porque tengo que deletrear mentalmente las letras en lugar de decirlo dentro de mi mente y dejar que mis dedos escriban automáticamente la palabra (como montar en bicicleta)

(Mi TypingTest.com benchmark = 136 WPM)

 9
Author: Mark Rejhon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 22:14:08

Todas las buenas respuestas - el comportamiento debe ser exactamente el mismo.

SIN EMBARGO - Solo supongamos que HIZO una diferencia. Supongamos que uno de ellos tomó 3 instrucciones más por iteración.

¿Debería importarte?

SÓLO si lo haces dentro del bucle casi nada, que es casi nunca el caso.

Mi punto es, hay micro-optimización y macro-optimización. Micro-optimización es como "conseguir un corte de pelo para perder peso".

 6
Author: Mike Dunlavey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-10 00:36:09
for(;;Sleep(50))
{
    // Lots of code
}

Es más claro que:

while(true)
{
    // Lots of code
    Sleep(50);
}

No es que esto se aplique si no está usando Sleep().

 6
Author: Armada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-23 05:12:21

No puedo imaginar que un compilador que valga la pena generaría ningún código diferente. Incluso si lo hiciera, no habría manera de determinar sin probar el compilador particular que era más eficiente.

Sin embargo, te sugiero que prefieras for(;;) por las siguientes razones:

  • Varios compiladores que he usado generarán una advertencia de expresión constante para while (true) con la configuración de nivel de advertencia adecuada.

  • En su ejemplo, la macro TRUE puede no se define como se espera

  • Hay muchas variantes posibles del bucle while infinito, como while(1), while(true), while(1==1) etc.; así que for(;;) es probable que resulte en una mayor consistencia.

 5
Author: Clifford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 22:34:37

El bucle "forever" es popular en sistemas embebidos como bucle de fondo. Algunas personas lo implementan como:

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

Y a veces se implementa como:

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

Y otra implementación es:

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

Un compilador de optimización debe generar el mismo o similar código ensamblador para estos fragmentos. Una nota importante: el tiempo de ejecución de los bucles no es una gran preocupación ya que estos bucles continúan para siempre, y se pasa más tiempo en la sección de procesamiento.

 4
Author: Thomas Matthews,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-09 22:14:06

Asumo que while (true) es más legible que for(;;) -- su aspecto como programador pierde algo en for loop :)

Y a quién le importa cuál es más rápido si hay

 2
Author: nik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-10 15:16:49

La razón más importante para usar "for(;;)" es el miedo de usar "while(TRUE)" cuando haces programación exploratoria. Es más fácil controlar la cantidad de repeticiones con "for", y también, más fácil convertir el bucle "for" en un infinito.

Por ejemplo, si está construyendo una función recursiva, puede limitar la cantidad de llamadas a la función antes de convertirla en un bucle infinito.

    for(int i=0;i<1000;i++) recursiveFunction(oneParam);

Cuando estoy seguro de mi función, entonces la convierto en un infinito bucle:

    for(;;) recursiveFunction(oneParam);
 2
Author: Ignacio Cortorreal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-29 05:49:39