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.
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.
ncc Says:
February 9th, 2009 at 11:19 pm
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
marcelogdiaz Says:
March 19th, 2009 at 2:22 pm
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;
}
derek Says:
March 21st, 2009 at 5:21 pm
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.
cuong Says:
May 23rd, 2009 at 12:50 am
@cuong
you’re an idiot.
Okonomiyaki3000 Says:
September 30th, 2009 at 8:24 pm
@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.
Yariv Says:
October 1st, 2009 at 5:17 am
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.
Vinod Says:
October 22nd, 2009 at 2:28 am
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
Tom Says:
November 2nd, 2009 at 3:07 pm
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().