Best Practice: Array Loops
If you've written much of anything in PHP, you've likely used a loop to process an array. Is there a right or wrong way to write one? Perhaps not. But is there a BEST way? It depends...
There are several ways to construct a loop and everybody will have their own favorite. Regardless of which you choose, we can demonstrate that there are indeed differences between them when CPU cycles count. Let's look at the three most common types: for, while, & foreach.
For the purposes of our discussion, I'm going to loop through an array called $bigArray.
for($i=0; $i < count($bigArray); $i++) {
$bigArray[$i]++;
}
$i=0;
while($i < count($bigArray)) {
$bigArray[$i]++;
$i++;
}
foreach($bigArray as $key => $value) {
$bigArray[$key]++;
}
All three implementations do essentially the same thing -- they increment the value of each item in the array. (This of course assumes the arrays are numerically indexed and contain only numeric values)
When we look at how much time each look takes to process an array with a million key/value pairs, we see that the for and while constructs measure pretty close to the same but the foreach loop takes nearly twice as long:
| Array Size: | 1,000,000 Entries |
| For Loop: | 0.38219 sec |
| While Loop: | 0.37016 sec |
| ForEach Loop: | 0.69293 sec |
Now we'll look at some slightly different but decidedly better implementations of those same two functions:
for($i=0, $max=count($bigArray); $i < $max; $i++) {
$bigArray[$i]++;
}
$i=0;
$max = count($bigArray);
while($i < $max) {
$bigArray[$i]++;
$i++;
}
You'll notice that instead of basing our comparison for each loop on the size of the array, we first assign that value to a separate variable. What we see now is a tremendous increase in speed for both loop types:
| Array Size: | 1,000,000 Entries |
| For Loop: | 0.38219 sec |
| For Loop w/Max: | 0.17383 sec |
| While Loop: | 0.37016 sec |
| While Loop w/Max: | 0.16463 sec |
| ForEach Loop: | 0.69293 sec |
Wow, less than half the time to complete each loop! Why so much faster? On our original "traditional" implementation, PHP has to execute the count() function on EVERY iteration through the loop. But by assigning that value ahead of time, it more than cuts in half the time required to complete the loop processing.
So, I think we can pretty safely say that when speed counts, while and for with the max predefined are the quickest methods. But they really will only work with numerically-indexed arrays. If you have an associative array, then foreach is the best option.
To illustrate why the max construct is better, I was recently shown a nice database utility class which put the contents of a returned query into a multi-dimensional array using a for loop. Its conditional was $i < mysql_num_rows($query). Well as we now know, that query was being executed for every value returned from the database...effectively doubling the number of SQL queries for every request. But by use the max construct, it's greatly sped up the database class and the entire application in turn. So it really pays to use the most efficient method you can and to get used to using it.
Just for giggles, we'll look at another way to process an array - the array_map function. It tells PHP to run through an entire array and apply a function to each member as such:
array_map(increment, $bigArray);
function increment($num) {
return $num++;
}
While it's not that efficient for this instance, it can be handy for something like trimming white space and line breaks from an array of text - array_map(trim, $textArray);. Just for reference, this code took 0.93637 seconds to process our same million entries.
blog comments powered by Disqus






