You have a block of code and you want to profile it to see how long each statement takes to execute.
Use the declare construct and the ticks directive:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
function profile($display = false) { static $times; switch ($display) { case false: // add the current time to the list of recorded times $times[] = microtime(); break; case true: // return elapsed times in microseconds $start = array_shift($times); $start_mt = explode(' ', $start); $start_total = doubleval($start_mt[0]) + $start_mt[1]; foreach ($times as $stop) { $stop_mt = explode(' ', $stop); $stop_total = doubleval($stop_mt[0]) + $stop_mt[1]; $elapsed[] = $stop_total - $start_total; } unset($times); return $elapsed; break; } } // register tick handler register_tick_function('profile'); // clock the start time profile(); // execute code, recording time for every statement execution declare (ticks = 1) { foreach ($_SERVER['argv'] as $arg) { print "$arg: " . strlen($arg) ."\n"; } } // print out elapsed times print "---\n"; $i = 0; foreach (profile(true) as $time) { $i++; print "Line $i: $time\n"; } |
The ticks directive allows you to execute a function on a repeatable basis for a block of code.
The number assigned to ticks is how many statements go by before the functions that are registered using register_tick_function() are executed.
In the Solution, we register a single function and have the profile() function execute for every statement inside the declare block.
If there are two elements in $_SERVER[‘argv’], profile() is executed six times: once when the clocks starts; twice for the two times through the foreach loop; another two when the print strlen($arg) line is executed; and finally, once when foreach returns false:
1 2 3 4 5 6 |
Line 1: 5.3882598876953E-5 Line 2: 5.6982040405273E-5 Line 3: 6.2942504882812E-5 Line 4: 6.5803527832031E-5 Line 5: 6.7949295043945E-5 Line 6: 6.9856643676758E-5 |
You can also set things up to call two functions every three statements:
1 2 3 4 5 6 |
register_tick_function('profile'); register_tick_function('backup'); declare (ticks = 3) { // code... } |
You can also pass additional parameters into the registered functions, which can be object methods instead of regular functions:
1 2 3 4 5 6 |
// pass "parameter" into profile() register_tick_function('profile', 'parameter'); // call $car->drive(); $car = new Vehicle; register_tick_function(array($car, 'drive')); |
If you want to execute an object method, pass the object and the name of the method encapsulated within an array.
This lets the register_tick_function() know you’re referring to an object instead of a function.
Call unregister_tick_function() to remove a function from the list of tick functions:
1 |
unregister_tick_function('profile'); |