Is there any difference in PHP between while(true)
and for(;;)
besides syntax and readability?

- 1,710
- 2
- 17
- 33
-
5@Touchpad I am curious to know the answer specific to PHP – Alastair Apr 07 '14 at 14:56
-
Is there preoptizations in php? :) – vp_arth Apr 07 '14 at 14:58
-
1http://codepad.viper-7.com/awq3Mh generally I am seeing a tiny bit faster performance from the `while(true)` – Michael Berkowski Apr 07 '14 at 14:59
-
1PHP is based on C++, so this would be a duplicate of the above question. There is no difference between the two. – Aziz Saleh Apr 07 '14 at 15:00
-
1...And it scales. The while loop seems consistently measurably faster on large loops http://codepad.viper-7.com/19nv5D Internally, I can't tell you why. – Michael Berkowski Apr 07 '14 at 15:02
-
2@AzizSaleh so PHP is compiled to C++ and then executed? I though PHP was written in C and compiled to its own bytecode. – Alastair Apr 07 '14 at 15:02
-
My bad, yes I meant C not C++ (I confuse them most of the time). – Aziz Saleh Apr 07 '14 at 15:14
-
2If you want to write less, you can just use `while(1)` – Al.G. Apr 07 '14 at 15:17
-
1@user3132718: `for(;;)` is even shorter (by one character). **The length doesn't matter, but readability does.** – Amal Murali Apr 07 '14 at 17:02
-
Are people actually choosing whether to use `while(true)` or `for(;;)` based on *how many opcodes are emitted*? In PHP? Isn't that somewhat, just *a little bit* of a micro-optimization? – Thomas Apr 08 '14 at 07:03
-
If you are saving 1 opcode inside a tight loop that only contains 10-20 opcodes, that's potentially a 5-10% speed increase, which could be significant. Before the question was asked, it was possible the answer was more than 1 opcode difference. – rjmunro Apr 08 '14 at 09:38
-
@Thomas the question was to understand the difference as far as the engine is concerned. The rational decision is still made based on readability, i.e. just use `while(true)` – Alastair Apr 08 '14 at 10:04
-
2Why was this put on hold as opinion-based? Maybe if the question asked about readability, but it explicitly excluded that. Crazy. – Ian Goldby Apr 08 '14 at 11:44
-
@IanGoldby It's reopened now. – Dejan Marjanović Apr 08 '14 at 13:07
1 Answers
Ok, so first off, let me say this: Use while(true)
, as it gives the most semantic meaning. You need to parse for (;;)
as it's not something you see often.
With that said, let's analyze:
Opcodes
The code
while(true) {
break;
}
echo "hi!";
Compiles down to the opcodes:
0: JMPZ(true, 3)
1: BRK(1, 3)
2: JMP(0)
3: ECHO("hi!")
So basically, it does a check if "true", and if not, jumps to the 4th opcode which is the echo opcode). Then it breaks (which is really just a static jump to the 4th opcode). Then the end of the loop would be an unconditional jump back to the original check
Compare that to:
for (;;) {
break;
}
echo "hi!";
Compiles down to:
0: JMPZNZ(true, 2, 4)
1: JMP(0)
2: BRK(1, 4)
3: JMP(1)
4: ECHO("hi!")
So we can immediately see that there's an extra opcode in the for(;;)
version.
Opcode Definitions
JMPZ(condition, position)
This opcode jumps if the condition is false
. If it is true
, it does nothing but advance one opcode.
JMPZNZ(condition, pos1, pos2)
This opcode jumps to pos1
if the condition is true, and pos2
if the condition is false.
JMP(position)
This opcode always jumps to the opcode at the specified position.
BRK(level, position)
This breaks level
levels to the opcode at position
ECHO(string)
Outputs the string
Are They The Same
Well, looking at the opcodes, it's clear that they are not identical. They are ==
, but not ===
. The while(true)
loop does a conditional jump followed by code followed by an unconditional jump. The for(;;)
loop does a conditional jump, followed by code, followed by an unconditional jump, followed by another unconditional jump. So it does an extra jump.
Opcache
In 5.5, the Optimizer portion of opcache will optimize static conditional jumps.
So that means the while(true)
code will optimize down to:
0: BRK(1, 2)
1: JMP(0)
2: ECHO("hi!")
And for(;;)
loop becomes:
0: BRK(1, 2)
1: JMP(0)
2: ECHO("hi!")
This is because the optimizer will find and optimize out jump-chains. So if you're using 5.5's built-in opcache, they will be identical...
Caution
This is a complete and utter micro-optimization to base a decision on. Use the readable one. Don't use one based on performance. The difference is there, but it's trivial.

- 13,194
- 14
- 74
- 96

- 163,128
- 34
- 264
- 314
-
1What’s the point of the `JMP(1)` as the first instruction in the optimized `while` version? Isn’t that effectively a no-op? Why doesn’t it get optimized away? – bdesham Apr 07 '14 at 16:10
-
1@bdesham: it does appear to get optimized away: http://lxr.php.net/xref/PHP_TRUNK/ext/opcache/Optimizer/pass3.c#134 It also looks like `JMP(2); JMP(0);` will get optimized down to `JMP(2);`, but I can't tell immediately if it will be optimized further to a NOP... – ircmaxell Apr 07 '14 at 16:28
-
1Excellent analysis! The identical behavior results in identical optimization (as it should, ideally), and the more semantic construction has fewer opcodes pre-optimization, making it the "better" choice for such micro-optimization, reinforcing the fact that `while(true)` should be preferred. – Brian S Apr 07 '14 at 20:33
-
3"Use while(true), as it gives the most semantic meaning. You need to parse for (;;) as it's not something you see often." Personally, I parse `(;;)` as a crying face, because why are you writing infinite loops? That makes me sad. – Mike G Apr 07 '14 at 21:02
-
-
@Dan it's *usually* indicative that there's something smelly going on. Not always, but usually. – Mike G Apr 07 '14 at 21:51
-
2@mikeTheLiar Any event loop is, technically, a simple infinite loop polling for input. As for the "you need to parse `for (;;)`" part -- it's actually quite often used in C **instead** of `while (1)` because linters complain less about the `for` variant [citation needed] – TC1 Apr 07 '14 at 22:11
-
@ST3 I used [codepad.viper-7.com](http://codepad.viper-7.com/) to do it online. But check out [a blog I wrote on the topic](http://blog.ircmaxell.com/2012/07/the-anatomy-of-equals-opcode-analysis.html) and [Another blog on the subject](http://blog.golemon.com/2008/01/understanding-opcodes.html)... – ircmaxell Apr 09 '14 at 01:22
-
@akled no. Because "semantic meaning" is context free. You just need to see the structure itself to understand what it does. As opposed to "pragmatic meaning" which requires understanding of the context (surrounding content) to understand the meaning implied. `foreach ($a as $b) {}` requires understanding of what `$a` may be (and its behaviors). Which is not semantic, but pragmatic meaning. `while(true)` is purely semantic, as nothing but the grammar presented in front of you is needed to decipher the meaning. – ircmaxell Apr 14 '14 at 17:56