PHP中while(true)和for(;;)之间有什么区别?

时间:2014-04-07 14:53:43

标签: php for-loop while-loop infinite-loop php-internals

除了语法和可读性之外,while(true)for(;;)之间的PHP有什么区别吗?

编辑:我不认为这是重复的 - 我想知道PHP特有的答案。就发动机而言,有什么真正的区别吗?他们编译成同样的东西吗?他们有相同的表现吗?

编辑2:我也不会认为相对性能和相关的OpCodes基于意见。在可读性方面存在意见空间,但这显然不是问题。

1 个答案:

答案 0 :(得分:91)

好的,首先,让我这样说:使用while(true),因为它提供了最多的语义含义。您需要解析for (;;),因为它不是您经常看到的内容。

话虽如此,让我们分析一下:

的Opcodes

代码

while(true) {
    break;
}
echo "hi!";

编译到操作码:

0: JMPZ(true, 3)
1: BRK(1, 3)
2: JMP(0)
3: ECHO("hi!")

所以基本上,它会检查" true"如果没有,则跳转到第4个操作码,即echo操作码。然后它中断(这实际上只是静态跳转到第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(条件,位置)

如果条件为false,则此操作码会跳转。如果它是true,它只会推进一个操作码。

JMPZNZ(条件,pos1,pos2)

如果条件为真,则此操作码跳转到pos1,如果条件为假,则跳转到pos2

JMP(位置)

此操作码始终跳转到指定位置的操作码。

BRK(级别,职位)

这会将level级别分解为position

处的操作码

ECHO(字符串)

输出字符串

它们是否相同

嗯,看看操作码,很明显它们并不相同。它们是==,但不是===while(true)循环执行条件跳转,然后是代码,后跟无条件跳转。 for(;;)循环执行条件跳转,然后是代码,接着是无条件跳转,然后是另一个无条件跳转。所以它做了额外的跳跃。

Opcache

在5.5中,opcache的优化器部分将optimize static conditional jumps

这意味着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,它们将完全相同......

注意

这是一个完整的,完全的微观优化,可以作出决定。使用可读的。不要根据表现使用一个。差异在那里,但它是微不足道的。