So I decided to actually quantify a few things, in the interest of getting some real numbers. Here is the baseline code, a loop which builds a big array of 100000 integers.
$x = array();
for ($idx=0; $idx<100000; $idx++)
$x[] = $idx;
Average time to execute: 85 ms. That includes the time to launch PHP, parse the program, run it, and exit. Now, I add another loop that iterates through the array:
for ($idx=0; $idx<count($x); $idx++) {
;
}
Average time to execute: 105 ms. When you subtract the 85 ms setup time, you can see it takes only 20 ms to iterate through a 100,000 member array.
Now we add the loop invariant code motion:
$m = count($x);
for($idx=0; $idx<$m; $idx++) {
;
}
Average time to execute: 90 ms.
On the one hand, this savings is huge. That's 5 ms loop iteration time instead of 20 ms. So you can argue that's a 75% savings!
On the other hand, it's 15 ms. Less time than most people will notice on an absurdly large array.
But this is an array that does nothing. Let's see what happens when we output some data:
$m = count($x);
for ($idx=0; $idx<$m; $idx++) {
echo $idx;
}
Now the execution time is 200 ms. Oh look, I only printed out the loop index. I didn't even output the contents of the array.
That's just silly. Let's change the program again to echo the contents of the array instead of just the look counter:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo $x[$idx];
New execution time is 212 ms. So it took 5% longer to access and echo the array contents than just echo the loop counter.
Let's take someone's earlier suggestion and unroll the loop. I've used this to great effect in C/C++ in the past:
$m = count($x);
for ($idx=0; $idx<$m; $idx+=5) {
echo $x[$idx];
echo $x[$idx+1];
echo $x[$idx+2];
echo $x[$idx+3];
echo $x[$idx+4];
}
Now we're talking! We're down to 206 ms. Oh wait, that's about a 3% improvement for some un-fun code. And the output looks terrible. It's just a string of numbers without whitespace or anything.
Let's get rid of the loop unrolling, and make the output a little nicer:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo "{$x[$idx]}\n";
Execution time is 400 ms. Huh. That's a lot of extra time (relatively speaking) just to get some formatting. Maybe using the string substitution is costing us something. Let's try string concatenation instead:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo $x[$idx] . "\n";
The new time is 390 ms. A little better. Let's try separating the numbers by a space instead of a newline:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo $x[$idx] . " ";
Oh wow, we're back down to 224 ms. Right on! But what happened? Well, I'm running all this on my Unix terminal, and it is justs plain slower to output the numbers on separate lines than it is to output them all on one line that wraps.
In other words, the speed of the terminal program's scrolling has a bigger effect than anything else we did.