PHP: foreach vs. while vs. for - The loop battle!
PHP has just one kind of array, it does not have separate lists, hash or maps, they are all combined in a "array". Iterating over such a array is a very common part so doing it wrong can lead to less performance.
In the following article i will do a short test which loop is the fastest.
First, the benchmark code:
$n = 1500000;
// Generating test array
$array = array();
$i = 0;
while($i < $n) {
$array[] = $i++;
}
/**
* Benchmark
*/
// Foreach
$time_start = microtime(true);
foreach($array as $a) {
$devnull = $a;
}
$time_end = microtime(true);
$time_foreach = $time_end-$time_start;
echo number_format($time_foreach, 3, '.', '')
." seconds - foreach()\n";
// While
$time_start = microtime(true);
$i = 0;
$length = count($array);
while($i<$length) {
$devnull = $array[$i++];
}
$time_end = microtime(true);
$time_while = $time_end-$time_start;
echo number_format($time_while, 3, '.', '')
." seconds - while()\n";
// For
$time_start = microtime(true);
$length = count($array);
for($i=0;$i<$length;++$i) {
$devnull = $array[$i];
}
$time_end = microtime(true);
$time_for = $time_end-$time_start;
echo number_format($time_for, 3, '.', '')
." seconds - for()\n";
?>
The result on my machine is:
0.506 seconds - while()
0.530 seconds - for()
So the winner in category speed is foreach()!
I do not want to let the comparison end here and look a little bit further.
Why did i write the for loop this way?
Because if i wrote
on each iteration the count() function would have been called and the loop would be damn slow!
Its also the same cause for the while() loop, which would be damn slow too.
As you know, programmers are lazy, they do not want to type that much. So lets look which loop needs less characters:
foreach: "foreach($a as $b){}" is 19 chars long.
while: "$i=0;$l=count($a);while($i++<$l){}" is 34 chars long.
for: "$l=count($a);for($i=0;$i<$l;++$i){}" is 35 chars long.
I would say foreach has also won this small test.
For a result i would say, use foreach because its the fastest and you can get the array key easily with "foreach($array as $key => $value)". But if you need only to iterate over a few entry's of a array, use while() because you can change $i to exit the loop. This is also possible in a for loop but these need more characters to type, and will be changed by the compiler internally to a while loop anyway.
No related posts.
You could also write something like this:
for($i=0,$length=count($array); $i<$length; ++$i) {
$devnull = $array[$i];
}
This way you also wont force the loop to call the count() on every iteration. But the code looks differently. Its a way to trick some people so the wont see the defined $length - hence they wont say that the cost of faster script is more lines of code.
Thanks Mike, thats a good hint.
I did not know this trick. Maybe i should read more about the ',' comma in PHP.
My pleasure :).
The situation I jumped on this idea was quite odd. I have read some fiery discussion on the web, the topic was something like:
- faster script vs. less coding
There was rather big flame about the loops, whether its better to call the count() within the loop on every iteration or to call it just once before the loop, but with the cost of more lines of code.
I thought: wait a minute, after we call for() we define $i, but its done just this once, then the loop doesnt go back to it - so why dont we define one more variable there?
Then I gave it a shoot and tested in different situations - it worked wery well so I just started to use it and tell people about it (if they didnt know this yet).
Cheers!
I prefer fast and tiny code :D
All what we mentioned is available in the PHP docu:
http://de3.php.net/manual/en/control-structures.for.php
Maybe we should a little bit more to save some time :D
Im almost always reading documentation on php.net but when its something that seems to be obvious - Im not.
Over the years it turned out that its ALWAYS good to read the whole documentation, even about the basic things - because theres always a posibility youll find something you didnt know before.
Example? For me, things like passing the whole arrays instead of singular variable to the particular built-in function, like strtr() - http://pl.php.net/strtr
Now Im using this with arrays in my own function that creates friendly URLs.
Sorry for offtop :).
[...] es dann nicht verwenden? Foreach ist wenn man dem hier glauben darf sogar ein stück schneller PHP - foreach vs. while vs. for - The loop battle! | Julius Beckmann Geändert von Creator (Gestern um 19:57 [...]
Try this
// Generating test array
$array = array();
$i = 0;
while($i < $n) {
$array[] = md5($i++);
}
...
This should be a better representation of a real world scenario. More often than not an array element will contain a string or another array so by hashing the numbers each element becomes 32 chars long.
When I run this modified benchmark the while loop comes out on top, and the foreach loop is the slowest.
hello, wouldn't argue that foreach is definitely faster in speed, but do you have any test done for memory usage between the few? have yet to do some real benchmarking, but at least from my application, foreach seems to be using significantly more memory than for loop.
any thoughts?
Hi Steven,
i had a short look on that and wrote some code for testing:
https://gist.github.com/1137776
Result:
while does not use any new ram, but the foreach loop will assign one new variable with "foreach($array => $entry) {..." when $entry is a new variable.
That is happening because the $entry variable wil stay after the loop is finished and has the last assigned value from array. But that should not result in noticeable ram increase, because $entry should be just a internal reference, as long as you have not modified it.
Hope that helps.
@mike: on my system this
$length = count($arr);
for($x = 0; $x < $length; $x++)
{
echo $arr[$x] . "";
}
is about four times faster than this
for($x = 0, $length = count($arr); $x < $length; $x++)
{
echo $arr[$x] . "";
}
HI!
Thanks for the nice compare!
On my local system i have the same results.
But if i use the Loops out of a function the foreach needs much more time.
function foreachLoop($array) {
// Foreach
$time_start = microtime(true);
foreach($array as $a) {
$devnull = $a;
}
$time_end = microtime(true);
return $time_end-$time_start;
}
This are my result:
0.142 seconds - foreach()
0.407 seconds - foreach() in function
0.159 seconds - while()
0.157 seconds - while() in function
0.150 seconds - for()
0.153 seconds - for() in function
I think speed depends on usage. Inline is the foreach faster. But in functions it is much slower.
Benji
I did a simple benchmark too. You can find it over here: http://www.wardt.info/php-benchmark-the-speed-of-foreach-for-and-while-loops-compared/