好吧,首先,让我说:使用while(true),因为它给出最语义的意义。你需要解析(;;),因为它不是你经常看到的东西。
说到这里,让我们分析一下:
操作码
代码
while(true) {
break;
}
echo "hi!";
编译到操作码:
0: JMPZ(true, 3)
1: BRK(1, 3)
2: JMP(0)
3: ECHO("hi!")
因此,基本上,它检查如果“真”,如果不是,跳转到第四操作码,它是回声操作码)。然后它断开(这只是一个静态跳转到第4个操作码)。然后循环的结束将是无条件跳回到原始检查
比较:
for (;;) {
break;
}
echo "hi!";
编译至:
0: JMPZNZ(true, 2, 4)
1: JMP(0)
2: BRK(1, 4)
3: JMP(1)
4: ECHO("hi!")
所以我们可以立即看到在for(;;)版本中有一个额外的操作码。
操作码定义
JMPZ(条件,位置)
如果条件为假,则此操作码跳转。如果它是真的,它什么也没有提前一个操作码。
JMPZNZ(condition,pos1,pos2)
如果条件为true,此操作码跳转到pos1,如果条件为假,则跳转到pos2。
JMP(位置)
这个操作码总是跳到指定位置的操作码。
BRK(级别,位置)
这打破了在位置的操作码的级别
ECHO(字符串)
输出字符串
他们是一样的
好了,看看操作码,很明显,它们不是相同的。它们是==,但不是===。 while(true)循环执行条件跳转,后面跟随着无条件跳转的代码。 for(;;)循环执行条件跳转,随后是代码,随后是无条件跳转,随后是另一个无条件跳转。所以它做一个额外的跳。
Opcache
这意味着while(true)代码将优化到:
0: BRK(1, 2)
1: JMP(0)
2: ECHO("hi!")
和for(;;)循环变成:
0: BRK(1, 2)
1: JMP(0)
2: ECHO("hi!")
这是因为优化器将找到并优化跳转链。所以如果你使用5.5的内置opcache,他们将是相同的…
警告
这是一个完全和完全的微优化,以作为决定的基础。使用可读的。不要使用基于性能的。区别在于,但它是微不足道的。