Sunday, July 5, 2009

Arrays Loop Benchmarking: foreach vs while

Yes yes, i am current obsessed with loads of PHP speed tests on my local machine. But today I worked on something interesting: foreach vs while loops for Arrays.

Remember one of my posts titled "PHP Loop Benchmarking - WHILE vs FOR"? It talks about your PHP scripts can be speed up using while loops instead of for loops?

Well, for Arrays, this is not the case at all.

In my test, i create an array with 100000 elements. Here's how I create the benchmarking array:
$a = array();
while($i++ < 100000){
$a[] = dechex(crc32(mt_rand().time()));
}


Then I move on to measure time taken to run through the array with a FOREACH loop:
foreach($a as $k){

}

The foreach run took 0.00826096534729 seconds.

Next, I measure the time taken to run through the array, with a WHILE loop:
$z = -1;
while($z++ < count($a)){
$k = $a[$z];
}

Amazingly, the run took 0.0426709651947 seconds - approximately 5 times slower than FOREACH loop.

Then I moved on to optimize the while loop. Instead of calling the count() function at every step, I will store the number of elements into a variable before the loop.
$z = -1;
$i = count($a);
while($z++ < $i){
$k = $a[$z];
}

As expected, the run speeds up and it took 0.0160219669342 seconds.

The reason behind the while loop being slow, is the fetching of element with "$k = $a[$z];". Once i removed that line, the optimized while loop (3rd test run) ran at 0.00645399093628 seconds - 0.002 s faster than FOREACH.

Note that the timings taken are an average of 5 runs spreaded across 5 mins (i.e. 1 run per minute) for the most accurate timings. Please note that the timings may differ from computer to computer. I am using Intel QuadCore 2.4GHz, 4GB RAM, Windows XP SP3, XAMPP 1.7.1, PHP 5.2.9.

2 comments:

fandi said...

Hi Sam,
Very useful info you got there. I am still trying to optimize my php queries - I am using foreach and it is used to generate reports.

Before this, I was using while loop. And it was slow. After using foreach, the loading time cut to become approx 5 seconds.

This is true for less than 100 records. For 1000+ data the query became slow again. About 10 seconds approx.

thephpdeveloper said...

@fandi - yea probably the thing results differently when used on large running applications.

this test ran with minimal data in the array records. only a CRC32 8 characters string was in each element of the array.

also, the array has natural incremental key/id, i.e. the key was assigned by PHP. 0, 1, 2, 3, 4

anyway fandi thanks for sharing as well =)