Apr 19

PHP For vs. Foreach

I have always believed that iterating an array using a foreach loop in php was slower than iterating through the same array using a standard for loop. I figured this because there is no foreach equivalent in the underlying native code that php is run on and therefore a standard for loop didn’t require any additional translations.

I have never read any concrete evidence as to which is faster and a quick google search didn’t provide any results. Thus I decided to setup a benchmark test myself. The question in mind for me was “Is it more efficient to loop through a given array with a for or foreach loop?” This is also assuming a standard indexed array and not an associative array or hash table. since you would pretty much only use a foreach for that anyway.

The test involved first filling an array 100,000 items by just counting up from zero. A for loop counting to 100,000 was then setup along with a foreach loop set to iterate through the pre-filled array. An extra loop was setup around each of the test loops to do the iterations multiple times. I like to do this to get more of an average running time because using time as a measurement in a multitasking environment isn’t exactly 100% accurate. The body of each loop was merely a continue statement to move on to the next cycle.
Here is the php code:


set_time_limit(0);
$array = array();
echo "Filling array\n";

for($index=0; $index < 100000; $index++)
{
     $array[$index] = $index;
} 

$start = time();
for($iteration = 0;$iteration < 10; $iteration++)
{
     for($index=0;$index < 100000;$index++)
     {
          continue;
     }
}
$end = time();

$duration = $end - $start;
echo "For loop: ".$duration;$start = time();

for($iteration=0; $iteration < 10; $iteration++)
{
     foreach ($array as $value)
     {
           continue;
     }
}
$end = time();

$duration = $end - $start; echo "\nForeach loop: ".$duration; 

The results went against what I originally thought about php. I changed the iteration counts and the array size to make sure there wasn’t any affect due to loop setups or such. The results were nearly always the same. The for loop took twice as long to iterate than the foreach. Performance with any code is highly dependent on the context it is used in (especially in php) but this shows me my original thoughts were wrong.

Results for the above:

Filling array
For loop: 21
Foreach loop: 11

The benchmark was run on a Macbook Pro 1.8 Ghz Core Duo with 1.5GB ram. The test was run via CLI on php version 5.2.0. No optimizers or opcode cache was used. Try it out on different configurations and post your results in the comments.

Related Entries

  • No related posts found.

20 Responses to “PHP For vs. Foreach”


  1. Henry Says:

    Thanks for putting this up. I’m a bit new to PHP but I’ve been at it for almost 6 months. It’s useful to know that foreach comes out quicker in a test. I have mainly used foreach because it allows the array to change and cuts the amount of variables down. Maybe that’s what makes it faster?


  2. WarriorDeluxe Says:

    Thanks for your test! I always thought the same: for is faster than foreach.

    I think you should add enviroment details to your test report. Which PHP Version did you use? accelerators used (XCache, APC etc.)? CLI Version? Hardware used?


  3. mastrboy Says:

    sure this test is correct, i runned the same one and got For loop: 1 Foreach loop:0

    got something more heavy i could use?

    Running on hp proliant dl360 g3


  4. derek Says:

    If your machine is fast enough to produce those low of times you could always try increasing the loop counts or array sizes to get a larger sample set to go off of.


  5. tiamokr Says:

    Thanks for your sharing, but the result i got is like below:

    Filling array
    For loop: 25
    Foreach loop: 28

    This is based on condition which is $iteration


  6. derek Says:

    Interesting. This is by no means meant to be an end all analysis. I only ran that on my macbook with its php configuration. I wouldn’t be surprised if some people received different results with different hardware and/or php versions or configurations. It does negate my initial thought that the for loop is always faster than the foreach though.


  7. geis Says:

    I would be interested in what version of PHP everyone was running. I could certainly be mistaken, but I believe the behavior of foreach (or maybe for) changed somewhat between php4 and php5. Any chance foreach is faster in one version and slower in another?

    The good news is, neither is slower by an order of magnitude or anything ridiculous.


  8. lobwedge Says:

    I changed all of the time() calls to microtime_float() calls using the function below because I was getting 1 or 0 as the results on an older server (a proliant or netserver) with 2G of RAM (PHP 5.1.6) and I get results very similar to this every time…

    For loop: 0.71562886238098
    Foreach loop: 0.87309694290161

    function microtime_float()
    {
    list($usec, $sec) = explode(” “, microtime());
    return ((float)$usec + (float)$sec);
    }


  9. remi visser Says:

    Hi man, I get results below;

    Filling array
    For loop: 0.163197994232

    Foreach loop: 0.140375137329

    (I used the microtime_float calls posted by lobwedge) I’m running php 5.

    Oh and here’s my tip for you for today; use the wordpress plugin ‘Preserve Code Formatting’ http://www.coffee2code.com/wp-plugins/ I use it on my blog and this plugin makes sure that my code’s preservrd (I noticed the line breaks ‘\n’ where stripslahsed).

    Have a nice day.


  10. Anon Says:

    I used the author’s original code with:
    iterations -> for, foreach:
    10 -> 1,0
    100 -> 6,4
    1000 -> 64, 45

    PHP 4


  11. Filipe Abreu Says:

    AFAIK, a iteration being faster than other doesn’t mean it has less CPU usage. I have listened to a case wich using a foreach loop caused the system to be overloaded, and using a for loop instead solved the CPU load. A wider benchmark test should be made, using multi-dimensional arrays and loops, and actually doing something with the values. These are used in real projects, so tests must be made simulating real conditions and real functionality. And also, a CPU and memory monitoring should be made. Time isn’t the only variable considered in benchmark tests. Anyway this is a great initiative and is very useful to the community. But it must be more accurate to be taken as a real proof of the foreach performance.


  12. icandothat Says:

    I think i just read an article about this in “php architect” entitled “killing the for loop”. I recommend reading it but a short excerpt after a great deal of testing says that “The benchmarking reveals that the for() loop is always fastest. The performance impact of range() varies, but general appears to be less than five times worse than a regular for() loop. XRangeIterator, when implemented in PHP is even slower.”
    keep in mind howerver that the difference in real time was like .0000068 seconds per iteration.


  13. ncc Says:

    Hi there, I am sure that this is a great benchmark code. However, I guess the author seem like for loop. :)

    I have a concern, in the real world, do you always know how many item in an array? So I have modified your code to use count($array) instead. Try this and you will be surprised.
    ———————–
    <?php

    set_time_limit(0);
    $array = array();
    echo “Filling array”;

    for($index=0; $index < 100000; $index++)
    {
    $array[$index] = $index;
    }

    $start = time();
    for($iteration = 0;$iteration < 100; $iteration++)
    {
    for($index=0;$index < count($array);$index++)
    {
    continue;
    }
    }
    $end = time();

    $duration = $end - $start;
    echo “For loop: “.$duration;

    $start = time();

    for($iteration=0; $iteration < 100; $iteration++)
    {
    foreach ($array as $value)
    {
    continue;
    }
    }
    $end = time();

    $duration = $end - $start; echo “Foreach loop: “.$duration;

    ?>
    ———————–

    Thank you,
    Cuong


  14. marcelogdiaz Says:

    I´ve doing some profiling using xdebug (by the way…an awesome tool…http://www.xdebug.org/ ), and I´ve realized that a ‘for’ is more (not so much) costly than a ‘foreach’, obviously it depends on the number of iterations and the process inside of the loop.
    I also realized that a foreach using the array_keys() to accessing the values is faster than the common foreach. For example:

    foreach (array_keys($data) as $key){
    $value = $data[$key];
    }

    is faster than…

    foreach ($data as $value_data){
    $value = $value_data;
    }


  15. derek Says:

    Cuong,

    Thanks for your comment. You are right in real world situations you will most likely never know the number of items in the array at the time of writing the code. I am pretty sure the reason you are seeing a significant difference is not directly because you used the count() function but more so for the spot you put the count function.

    Putting count() withing the for loop declaration will cause the script to count the items in the array at every iteration of the loop. A better practice and benchmark would be to calculate the count before you enter any of the for loops. Since the count of the array is not changing, there is no need to calculate it more than once.


  16. cuong Says:

    @cuong

    you’re an idiot.


  17. Okonomiyaki3000 Says:

    @marcelogdiaz

    That’s a very interesting claim. I have a theory as to why that might be. If your foreach looks like this:

    foreach($array as $value) {}

    Then ‘$value’ is actually a copy of the data stored in the array. The copy operation might be expensive if your array is populated with big objects or arrays. Have you ever tested your ‘array_keys’ technique against:

    foreach($array as &$value) {}

    In this case, ‘$value’ is just a reference, so a full copy isn’t made. It only works in php 5 and up but I suspect it will be as fast or faster than using array_keys.


  18. Yariv Says:

    The original benchmark code is producing a different result if the foreach is stated:
    foreach ($array as $index => $value){…}
    (the assignment to $index costs, but is needed if we would like to have the same functionality as with the $array[$index] in the for loop)
    the performance then is little slower than the for loop.


  19. Vinod Says:

    Hi,
    I had also tried this example using microtime function of php setting the float value to TRUE.

    I got the following results

    1) 10 iterations
    For loop: 0.109605073929
    Foreach loop: 0.121420145035
    2) 100 iterations
    For loop: 1.14140582085
    Foreach loop: 1.21752905846


  20. Tom Says:

    Lol!

    Got: “Filling array For loop: 0.222928 Foreach loop: 0.189883″ on my laptop with Php 5.3 on Windows XP.

    I am using microtime() instead of time().

Leave a Reply