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:

<?php

$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.344 seconds - foreach()
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?

$length = count($array);
for($i=0;$i<$length;++$i) {
  $devnull = $array[$i];
}

Because if i wrote

for($i=0;$i<count($array);++$i)

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.


 
 
 

12 Kommentare zu “PHP: foreach vs. while vs. for - The loop battle!”

  1. Mike 4. Oktober 2009 um 17:43

    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.

  2. Julius 4. Oktober 2009 um 18:29

    Thanks Mike, thats a good hint.
    I did not know this trick. Maybe i should read more about the ',' comma in PHP.

  3. Mike 5. Oktober 2009 um 00:40

    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!

  4. Julius 5. Oktober 2009 um 09:35

    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

  5. Mike 5. Oktober 2009 um 23:23

    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 :).

  6. Datenbankeinträge selectieren und löschen - php.de 10. Dezember 2009 um 11:40

    [...] 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 [...]

  7. Sam 22. März 2010 um 11:11

    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.

  8. Steven T 9. August 2011 um 15:58

    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?

  9. Julius 10. August 2011 um 21:01

    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.

  10. huck 28. Februar 2012 um 01:13

    @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] . "";
    }

  11. BergBenji 26. Juli 2012 um 10:48

    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

  12. Richard Wardt van Duijvenbode 28. Februar 2013 um 04:03

    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/