PHP Script execution time and maximum workaround
Ever wondered how long your PHP scripts were taking to execute? Or maybe you’ve broken the maximum execution time limit on your server, as defined in your php.ini’s max_execution_time directive. Well, dealing with PHP script execution time is actually quite easy. In this mini tutorial, I’ll show you how to measure your PHP script execution time, include monitoring at different stages of the process, and work around your max execution time limit.
Measure script execution time
This is the easiest part. PHP’s microtime() function will give you the current timestamp in microseconds (you need that level of precision for script execution time). However, microtime() will give you a value like 0.13554500 978913621, when what you really want is 978913621.13554500 (the 0 taken off the decimal section and added on to the integer). We can take care of this easily with a function we’ll call microtime_float().
So, to implement script execution time, we just take this value at the start of the script and at (or near) the end, then subtract them. First, at the very start of your page’s code, add this function:
function microtime_float()
{
list($utime, $time) = explode(" ", microtime());
return ((float)$utime + (float)$time);
}
$script_start = microtime_float();
Then at the end, add this:
$script_end = microtime_float(); echo "Script executed in ".bcsub($script_end, $script_start, 4)." seconds.";
Measure script execution time in stages
We can use milestones in a script to track how certain sections of code are performing. The best way to achieve this is a simple function with some static variable inside. However, needs can quickly get complicated, so I built a simple static class to handle everything. Include this class in your application:
<?php
class ScriptTimer {
static $milestones;
function microtime_float() {
list($utime, $time) = explode(" ", microtime());
return ((float)$utime + (float)$time);
}
function timing_milestone($name) {
self::$milestones[] = array($name, self::microtime_float());
}
function dump_profile($return = false) {
self::$milestones[] = array('finish', self::microtime_float());
$output = '<table border="1">'.
'<tr><th>Milestone</th><th>Diff</th><th>Cumulative</th></tr>';
foreach (self::$milestones as $elem => $data) {
$output .= '<tr><td>'.$data[0].'</td>'.
'<td>'.round(($elem ? $data[1] - self::$milestones[$elem - 1][1]: '0'), 5).'</td>'.
'<td>'.round(($data[1] - self::$milestones[0][1]), 5).'</td></tr>';
}
$output .= '</table>';
if ($return) return $output;
echo $output;
}
}
As you can see, it’s a fairly simple class. It basically stores an array of milestones, each named, in ScriptTimer::$milestones. Each time you call ScriptTimer::timing_milestone(), you pass it a name of the current milestone. This might be ‘begin’, ‘init db’, ‘fetch rss’, ‘end’, or anything you like. When you call ScriptTimeer::dump_profile(), it runs through all these milestones and generates a HTML report. Trying it out in a real application results in something like the following:

It’s no full-on profiler, but it can still prove highly useful in quickly performance testing your application. To use it, just call ScriptTimer::timing_milestone(’some milestone name’) at major sections of your code. This is the testing script I used:
ScriptTimer::timing_milestone('begin');
usleep(3000); // do some db stuff
ScriptTimer::timing_milestone('db ready');
usleep(5200); // do some cache stuff
ScriptTimer::timing_milestone('caches primed');
usleep(8000); // render the output
ScriptTimer::timing_milestone('all output');
usleep(600); // clean up
ScriptTimer::timing_milestone('garbage collected');
ScriptTimer::dump_profile();
I’ve used the usleep() function to simulate loading time – don’t do this in your real application! Just add the ScriptTimer::timing_milestone() calls in, and call ScriptTimer::dump_profile() at the end. No need to initialise; the class works statically for simplicity.
Workaround for max_execution_time limit
Depending on your server configuration, you should be able to work around the max_execution_time script execution time limit very easily. A call to ini_set() should change the value of max_execution_time for the current execution, like so:
ini_set('max_execution_time', '0'); // 0 = no limit.
Tags: PHP, php performance, php tips






September 11th, 2009 at 11:47 am
Thanks!, exactly what I was looking for.