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 arrayn"; 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
- 08.09.07: Read-Only Member Variables with PHP 5 1 comments
- 01.04.08: California, BarcampOrlando and OrlandoPHP 1 comments
- 23.09.07: First Annual Barcamp Orlando 0 comments
Derek is a software and web developer in Orlando, FL. Check back often for updates on Orlando and Technology.
Henry Says:
May 23rd, 2007 at 11:27 am
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?
WarriorDeluxe Says:
June 3rd, 2007 at 4:52 am
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?
mastrboy Says:
September 6th, 2007 at 5:23 am
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
derek Says:
September 6th, 2007 at 8:14 am
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.
tiamokr Says:
September 12th, 2007 at 4:49 am
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
derek Says:
September 12th, 2007 at 8:15 am
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.
geis Says:
November 3rd, 2007 at 10:13 am
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.
lobwedge Says:
November 29th, 2007 at 7:03 pm
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);
}
remi visser Says:
February 5th, 2008 at 3:42 am
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.
Anon Says:
April 4th, 2008 at 11:26 am
I used the author’s original code with:
iterations -> for, foreach:
10 -> 1,0
100 -> 6,4
1000 -> 64, 45
PHP 4
Filipe Abreu Says:
May 9th, 2008 at 5:27 pm
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.
icandothat Says:
May 29th, 2008 at 6:04 pm
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.