Benchmarking PHP Code
In my last post - Best Practice: Array Loops, I demonstrated timing differences between several different array loops. I was then asked by a friend how I did the testing. So in this post, I'll show you the entire test script I put together so maybe you can use the ideas on your own to do some benchmarking.
Here's the entire script I wrote to do this testing:
<?php
// needed to cope with a million entry array
ini_set('memory_limit', '512M');
if($_POST['limit'] && $_POST['limit'] < 1000001) {
$limit = $_POST['limit'];
} else {
$limit = 5000;
}
$bigArray = fillArray($limit);
#######################################################
$start = microtime(TRUE);
for($i=0; $i<count($bigArray); $i++) {
$bigArray[$i]++;
#$bigArray[$i] = increment($bigArray[$i]);
}
$results['forNormal']['time'] = microtime(TRUE) - $start;
$results['forNormal']['name'] = 'For Loop';
#######################################################
$start = microtime(TRUE);
for($i=0, $max=count($bigArray); $i<$max; $i++) {
$bigArray[$i]++;
#$bigArray[$i] = increment($bigArray[$i]);
}
$results['forMax']['time'] = microtime(TRUE) - $start;
$results['forMax']['name'] = 'For Loop w/Max';
#######################################################
$start = microtime(TRUE);
$i=0;
while($i < count($bigArray)) {
$bigArray[$i]++;
#$bigArray[$i] = increment($bigArray[$i]);
$i++;
}
$results['whileNormal']['time'] = microtime(TRUE) - $start;
$results['whileNormal']['name'] = 'While Loop';
#######################################################
$start = microtime(TRUE);
$i=0;
$max = count($bigArray);
while($i < $max) {
$bigArray[$i]++;
#$bigArray[$i] = increment($bigArray[$i]);
$i++;
}
$results['whileMax']['time'] = microtime(TRUE) - $start;
$results['whileMax']['name'] = 'While Loop w/Max';
#######################################################
$start = microtime(TRUE);
while(list($key, $value) = each($bigArray))
{
$bigArray[$key]++;
#$bigArray[$key] = increment($bigArray[$key]);
}
$results['whileEach']['time'] = microtime(TRUE) - $start;
$results['whileEach']['name'] = 'While Each';
#######################################################
$start = microtime(TRUE);
foreach($bigArray as $key => $value) {
$bigArray[$key]++;
#$bigArray[$key] = increment($bigArray[$key]);
}
$results['forEach']['time'] = microtime(TRUE) - $start;
$results['forEach']['name'] = 'For Each';
#######################################################
$start = microtime(TRUE);
array_map(increment, $bigArray);
$results['arrayMap']['time'] = microtime(TRUE) - $start;
$results['arrayMap']['name'] = 'Array_Map';
#######################################################
echo "<table width=\"300\" cellspacing=\"3\">\n";
echo "<tr><td width=\"50%\"><strong>Array Size:</strong></td><td width=\"50%\"><strong>$limit</strong></td></tr>\n";
foreach($results AS $test) {
echo "<tr><td>".$test['name']."</td><td>".sprintf("%01.6f", $test['time'])."</td></tr>\n";
}
echo "</table>";
echo '<form action="'.$_SERVER['PHP_SELF'].'" method="post">';
echo '<input name="limit" value="'.$limit.'" />';
echo '<input type="submit" value="Update"></form>';
echo '<i>Max Value: 1000000</i>';
#######################################################
function increment($num) {
return $num++;
}
function fillArray($limit) {
// build huge array
for($i=0; $i<$limit; $i++) {
$array[] = $i;
}
return $array;
}
?>
First off, we use the ini_set command to increase the amount of per-process memory PHP will allow us to have. If you don't increase it above defaults, you'll find that you will be limited in the size of the array you can test with. I'm using a setting of 512M, but then I run a dedicated server with dual quad-core Xeons and 4GB of RAM...so overhead is not usually a problem. Most shared hosting won't allow that high a setting, but your mileage may vary.
Next we'll check for a value from our input box and make sure it's not too high. If we have nothing, we use a base limit of 5,000. Then we call our fillArray() function to create us an array to play with.
Now is when the real benchmarking starts. We use the microtime() function with the TRUE modifier to get the unix time with microseconds included. This gives us very highly accurate measurements of time. If you're still on PHP4 (why???) you can use this little function instead:
function mtime() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
We store the time before we start then again when we're done. We put that in an associative array so we can print it later. (aren't arrays fun!) After we've run all our tests, we'll output the data in a handy table. We use foreach to loop through our results array and put the stored values on a line of the table.
I realize this is a bit simplistic and we're only testing a single thing - an array loop in this case - but the same methods can be used to measure all sorts of things. It can be very handy to use benchmarking or timing checks to find which method works the best for an individual task. Because knowing what works the best will help you create lean, fast code with less chance for potential bottlenecks down the road.
Hope this helps!
blog comments powered by Disqus






