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

Ala*_*air 42 php for-loop infinite-loop while-loop php-internals

有没有之间的PHP任何差异while(true)for(;;)除了语法和可读性?

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

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

irc*_*ell 91

好吧,首先,让我这样说:使用while(true),因为它给出了最大的语义含义.你需要解析,for (;;)因为它不是你经常看到的东西.

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

操作码

代码

while(true) {
    break;
}
echo "hi!";
Run Code Online (Sandbox Code Playgroud)

编译到操作码:

0: JMPZ(true, 3)
1: BRK(1, 3)
2: JMP(0)
3: ECHO("hi!")
Run Code Online (Sandbox Code Playgroud)

所以基本上,它检查是否为"true",如果不是,则跳转到第4个操作码,即echo操作码.然后它中断(这实际上只是静态跳转到第4个操作码).然后循环结束将无条件跳回到原始检查

比较一下:

for (;;) {
    break;
}
echo "hi!";
Run Code Online (Sandbox Code Playgroud)

编译为:

0: JMPZNZ(true, 2, 4)
1: JMP(0)
2: BRK(1, 4)
3: JMP(1)
4: ECHO("hi!")
Run Code Online (Sandbox Code Playgroud)

所以我们可以立即看到版本中有一个额外的操作码for(;;).

操作码定义

JMPZ(条件,位置)

如果条件是这个操作码跳转false.如果是true,它只会推进一个操作码.

JMPZNZ(条件,pos1,pos2)

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

JMP(位置)

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

BRK(级别,位置)

这打破level了操作码的等级position

ECHO(串)

输出字符串

他们是一样的吗?

那么,看看操作码,很明显它们并不完全相同.它们是==,但不是===.该while(true)循环做一个条件跳转之后的代码,然后无条件跳转.该for(;;)循环做一个条件跳转,其次是代码,然后无条件跳转,紧接着又无条件跳转.所以它做了额外的跳跃.

Opcache

在5.5中,opcache的优化器部分将优化静态条件跳转.

这意味着while(true)代码将优化到:

0: BRK(1, 2)
1: JMP(0)
2: ECHO("hi!")
Run Code Online (Sandbox Code Playgroud)

for(;;)循环变为:

0: BRK(1, 2)
1: JMP(0)
2: ECHO("hi!")
Run Code Online (Sandbox Code Playgroud)

这是因为优化器将找到并优化跳链.所以如果你使用5.5的内置opcache,它们将是相同的......

警告

这是一个完整的,完全的微观优化,可以作出决定.使用可读的.不要使用基于性能的.差异在那里,但它是微不足道的.

  • "使用while(true),因为它给出了最大的语义含义.你需要解析(;;),因为它不是你经常看到的东西." 就个人而言,我解析`(;;)`作为一个哭泣的脸,因为你为什么要写无限循环?那样令我伤心. (3认同)
  • @mikeTheLiar从技术上讲,任何事件循环都是一个简单的无限循环轮询输入.至于"你需要解析`(;;)`"部分 - 它实际上经常用于C**而不是**的while(1)`因为linters抱怨'for`变体[引用]需要] (2认同)