switch - ¿Cuál es la diferencia entre while(true) y for(;;) en PHP?
switch php (1)
¿Hay alguna diferencia en PHP entre while(true)
y for(;;)
además de la sintaxis y la legibilidad?
Editar: No consideraría esto como un duplicado. Quiero saber la respuesta específica a PHP. ¿Hay alguna diferencia real en lo que respecta al motor? ¿Compilan a la misma cosa? ¿Tienen el mismo rendimiento?
Edición 2: Tampoco consideraría que el rendimiento relativo y los OpCodes asociados se basen en la opinión. Hay margen para la opinión en la legibilidad pero esta no es explícitamente la pregunta.
Ok, entonces primero déjenme decir esto: Use while(true)
, ya que da el significado más semántico . Necesita analizar for (;;)
ya que no es algo que vea a menudo.
Dicho esto, analicemos:
Opcodes
El código
while(true) {
break;
}
echo "hi!";
Compila hasta los códigos de operación:
0: JMPZ(true, 3)
1: BRK(1, 3)
2: JMP(0)
3: ECHO("hi!")
Básicamente, hace una comprobación si es "verdadero", y si no, salta al 4º código de operación que es el código de operación del eco). Luego se rompe (que en realidad es solo un salto estático al 4º código de operación). Entonces, el final del ciclo sería un salto incondicional a la verificación original
Compare eso con:
for (;;) {
break;
}
echo "hi!";
Compila hasta:
0: JMPZNZ(true, 2, 4)
1: JMP(0)
2: BRK(1, 4)
3: JMP(1)
4: ECHO("hi!")
De modo que podemos ver inmediatamente que hay un código de operación adicional en la versión for(;;)
.
Definiciones de código de operación
JMPZ (condición, posición)
Este código de operación salta si la condición es false
. Si es true
, no hace más que avanzar un opcode.
JMPZNZ (condición, pos1, pos2)
Este código de operación salta a pos1
si la condición es verdadera, y pos2
si la condición es falsa.
JMP (posición)
Este código de operación siempre salta al código de operación en la posición especificada.
BRK (nivel, posición)
Esto rompe los niveles de level
en el código de operación en la position
ECHO (cadena)
Da salida a la cadena
Son lo mismo
Bueno, mirando los códigos de operación, está claro que no son idénticos. Son ==
, pero no ===
. El ciclo while(true)
realiza un salto condicional seguido de un código seguido de un salto incondicional. El bucle for(;;)
realiza un salto condicional, seguido de un código, seguido de un salto incondicional, seguido de otro salto incondicional. Entonces hace un salto extra.
Opcache
En 5.5, la porción Optimizer de opcache optimizará los saltos condicionales estáticos .
Eso significa que el código while(true)
se optimizará hasta:
0: BRK(1, 2)
1: JMP(0)
2: ECHO("hi!")
Y for(;;)
loop se convierte en:
0: BRK(1, 2)
1: JMP(0)
2: ECHO("hi!")
Esto se debe a que el optimizador encontrará y optimizará las cadenas de salto. Entonces, si estás usando el opcache incorporado de 5.5, serán idénticos ...
Precaución
Esta es una micro optimización completa y completa para tomar una decisión. Usa el que se puede leer No use uno basado en el rendimiento. La diferencia está ahí, pero es trivial.