time_start = ""; $this->numStarts = 0; } public function start(){ if($this->numStarts == 0){ $this->time_start = microtime(true); } $this->numStarts++; } public function stop(){ $this->numStarts--; return microtime(true); } public function isStopped(){return ($this->numStarts == 0);} public function getStartTime(){return $this->time_start;} } } //// // Marks the beginning of a chunk of code for the profiler to analyze. //// function profiler_beginSection($sectionName){ if(RUN_PROFILER){ GLOBAL $profiler_timers; if(isset($profiler_timers[$sectionName])){ $profiler_timers[$sectionName]->start(); // doesn't change the time, just allows this nested call to be ignored. } else { $timer = new Profiler_Timer(); $timer->start(); $profiler_timers[$sectionName] = $timer; } } } // end profiler_beginSection() //// // Marks the end of a chunk of code for the profiler to analyze. //// function profiler_endSection($sectionName){ if(RUN_PROFILER){ GLOBAL $profiler_timers,$profiler_stats; if(isset($profiler_timers[$sectionName])){ $timer = $profiler_timers[$sectionName]; $time_end = $timer->stop(); if($timer->isStopped()){ $time_start = $timer->getStartTime(); if(! isset($profiler_stats[$sectionName])){ $profiler_stats[$sectionName] = array(0,0); } $profiler_stats[$sectionName][PROFILER_STATS_TOTAL_TIME] += ($time_end - $time_start); $profiler_stats[$sectionName][PROFILER_STATS_NUM_RUNS]++; unset($profiler_timers[$sectionName]); // done with this timer, remove it from the group of active timers } } else { print "WARNING: Profiler: Trying to end a section which does not have a timer running: \"$sectionName\"."; if(isset($profiler_stats[$sectionName])){ print " There are stats for this section-name, so the section may have already been ended."; } print "\n"; } } } // end profiler_endSection() //// // Displays the results of the profiler. // If there are any open timers, this just closes them. // // TODO: Either chose a logical sorting method (as-used, alphabetical, by total||average time, by number of calls) or allow // a sorting type to be passed in or configured. Another option would be to use jQuery sorttables. // // WARNING: After this function is called, if there were any timers open it will no longer be accurate to call this function // again. A good rule to follow is to call this function only once per page-load unless you understand what this means. //// function profiler_printResults(){ if(RUN_PROFILER){ // Close all open timers. GLOBAL $profiler_timers,$profiler_stats,$profiler_startedAt; $hangingTimers = array(); print "
\n";
while(count($profiler_timers) > 0){
foreach($profiler_timers as $sectionName=>$timer){
print "WARNING: Profiler: Closing hanging timer... \"$sectionName\".\n";
$hangingTimers[] = $sectionName;
profiler_endSection($sectionName);
}
}
// Go through the stats and display the table.
$totalTime = $totalRuns = 0;
$precision = 5; // chosen arbitrarily... number of decimal points to display in the results
print "| Section Name | total(sec) | calls | ave(sec) |
|---|---|---|---|
| $sectionName | "; print "".number_format($total, $precision, '.', '')." | "; print "$numRuns | "; print "".number_format(($total / $numRuns), $precision, '.', '')." | "; print "
| Totals | "; print "".number_format($totalTime, $precision, '.', '')." | "; print "$totalRuns | "; print "".number_format(($totalTime / $totalRuns), $precision, '.', '')." | "; print "