253 lines
7.2 KiB
PHP
253 lines
7.2 KiB
PHP
|
<?php
|
||
|
|
||
|
/********************************************************************************\
|
||
|
* Copyright (C) Carl Taylor (cjtaylor@adepteo.com) *
|
||
|
* Copyright (C) Torben Nehmer (torben@nehmer.net) for Code Cleanup *
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or *
|
||
|
* modify it under the terms of the GNU General Public License *
|
||
|
* as published by the Free Software Foundation; either version 2 *
|
||
|
* of the License, or (at your option) any later version. *
|
||
|
* *
|
||
|
* This program is distributed in the hope that it will be useful, *
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||
|
* GNU General Public License for more details. *
|
||
|
* *
|
||
|
* You should have received a copy of the GNU General Public License *
|
||
|
* along with this program; if not, write to the Free Software *
|
||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||
|
* \********************************************************************************/
|
||
|
|
||
|
/// Enable multiple timers to aid profiling of performance over sections of code
|
||
|
|
||
|
/**
|
||
|
* @package Core
|
||
|
*/
|
||
|
class Profiler {
|
||
|
var $description;
|
||
|
var $startTime;
|
||
|
var $endTime;
|
||
|
var $initTime;
|
||
|
var $cur_timer;
|
||
|
var $stack;
|
||
|
var $trail;
|
||
|
var $trace;
|
||
|
var $count;
|
||
|
var $running;
|
||
|
|
||
|
/**
|
||
|
* @var bool
|
||
|
*/
|
||
|
private $trace_enabled;
|
||
|
/**
|
||
|
* @var bool
|
||
|
*/
|
||
|
private $output_enabled;
|
||
|
|
||
|
/**
|
||
|
* Initialise the timer. with the current micro time
|
||
|
* @param bool $output_enabled
|
||
|
* @param bool $trace_enabled
|
||
|
*/
|
||
|
function __construct( $output_enabled = false, $trace_enabled = false ) {
|
||
|
$this->description = [];
|
||
|
$this->startTime = [];
|
||
|
$this->endTime = [];
|
||
|
$this->initTime = 0;
|
||
|
$this->cur_timer = "";
|
||
|
$this->stack = [];
|
||
|
$this->trail = "";
|
||
|
$this->trace = "";
|
||
|
$this->count = [];
|
||
|
$this->running = [];
|
||
|
$this->initTime = $this->getMicroTime();
|
||
|
$this->output_enabled = $output_enabled;
|
||
|
$this->trace_enabled = $trace_enabled;
|
||
|
$this->startTimer( 'unprofiled' );
|
||
|
}
|
||
|
|
||
|
// Public Methods
|
||
|
|
||
|
/**
|
||
|
* Start an individual timer
|
||
|
* This will pause the running timer and place it on a stack.
|
||
|
* @param string $name name of the timer
|
||
|
* @param string optional $desc description of the timer
|
||
|
*/
|
||
|
function startTimer( $name, $desc = "" ) {
|
||
|
$this->trace .= "start $name\n";
|
||
|
$n = array_push( $this->stack, $this->cur_timer );
|
||
|
$this->__suspendTimer( $this->stack[$n - 1] );
|
||
|
$this->startTime[$name] = $this->getMicroTime();
|
||
|
$this->cur_timer = $name;
|
||
|
$this->description[$name] = $desc;
|
||
|
if ( !array_key_exists( $name, $this->count ) ) {
|
||
|
$this->count[$name] = 1;
|
||
|
} else {
|
||
|
$this->count[$name]++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Stop an individual timer
|
||
|
* Restart the timer that was running before this one
|
||
|
* @param string $name name of the timer
|
||
|
*/
|
||
|
function stopTimer( $name ) {
|
||
|
$this->trace .= "stop $name\n";
|
||
|
$this->endTime[$name] = $this->getMicroTime();
|
||
|
if ( !array_key_exists( $name, $this->running ) ) {
|
||
|
$this->running[$name] = $this->elapsedTime( $name );
|
||
|
} else {
|
||
|
$this->running[$name] += $this->elapsedTime( $name );
|
||
|
}
|
||
|
$this->cur_timer = array_pop( $this->stack );
|
||
|
$this->__resumeTimer( $this->cur_timer );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* measure the elapsed time of a timer without stoping the timer if
|
||
|
* it is still running
|
||
|
* @param $name
|
||
|
* @return int|mixed
|
||
|
*/
|
||
|
function elapsedTime( $name ) {
|
||
|
// This shouldn't happen, but it does once.
|
||
|
if ( !array_key_exists( $name, $this->startTime ) ) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if ( array_key_exists( $name, $this->endTime ) ) {
|
||
|
return ( $this->endTime[$name] - $this->startTime[$name] );
|
||
|
} else {
|
||
|
$now = $this->getMicroTime();
|
||
|
|
||
|
return ( $now - $this->startTime[$name] );
|
||
|
}
|
||
|
}//end start_time
|
||
|
|
||
|
/**
|
||
|
* Measure the elapsed time since the profile class was initialised
|
||
|
*
|
||
|
*/
|
||
|
function elapsedOverall() {
|
||
|
$oaTime = $this->getMicroTime() - $this->initTime;
|
||
|
|
||
|
return ( $oaTime );
|
||
|
}//end start_time
|
||
|
|
||
|
/**
|
||
|
* print out a log of all the timers that were registered
|
||
|
* @param bool $enabled
|
||
|
*/
|
||
|
function printTimers( $enabled = false ) {
|
||
|
if ( $this->output_enabled || $enabled ) {
|
||
|
$TimedTotal = 0;
|
||
|
$tot_perc = 0;
|
||
|
ksort( $this->description );
|
||
|
print( "<pre>\n" );
|
||
|
$oaTime = $this->getMicroTime() - $this->initTime;
|
||
|
echo "============================================================================\n";
|
||
|
echo " PROFILER OUTPUT\n";
|
||
|
echo "============================================================================\n";
|
||
|
print( "Calls Time Routine\n" );
|
||
|
echo "-----------------------------------------------------------------------------\n";
|
||
|
foreach ( $this->description as $key => $val ) {
|
||
|
$t = $this->elapsedTime( $key );
|
||
|
if ( isset( $this->running[$key] ) ) {
|
||
|
$total = $this->running[$key];
|
||
|
} else {
|
||
|
$total = 0;
|
||
|
}
|
||
|
$count = $this->count[$key];
|
||
|
$TimedTotal += $total;
|
||
|
$perc = ( $total / $oaTime ) * 100;
|
||
|
$tot_perc += $perc;
|
||
|
// $perc=sprintf("%3.2f", $perc );
|
||
|
printf( "%3d %3.4f ms (%3.2f %%) %s\n", $count, $total * 1000, $perc, $key );
|
||
|
}
|
||
|
|
||
|
echo "\n";
|
||
|
|
||
|
$missed = $oaTime - $TimedTotal;
|
||
|
$perc = ( $missed / $oaTime ) * 100;
|
||
|
$tot_perc += $perc;
|
||
|
// $perc=sprintf("%3.2f", $perc );
|
||
|
printf( " %3.4f ms (%3.2f %%) %s\n", $missed * 1000, $perc, "Missed" );
|
||
|
|
||
|
echo "============================================================================\n";
|
||
|
|
||
|
printf( " %3.4f ms (%3.2f %%) %s\n", $oaTime * 1000, $tot_perc, "OVERALL TIME" );
|
||
|
|
||
|
echo "============================================================================\n";
|
||
|
|
||
|
print( "</pre>" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param bool $enabled
|
||
|
*/
|
||
|
function printTrace( $enabled = false ) {
|
||
|
if ( $this->trace_enabled || $enabled ) {
|
||
|
print( "<pre>" );
|
||
|
print( "Trace\n$this->trace\n\n" );
|
||
|
print( "</pre>" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Internal Use Only Functions
|
||
|
|
||
|
/**
|
||
|
* Get the current time as accuratly as possible
|
||
|
*
|
||
|
*/
|
||
|
function getMicroTime() {
|
||
|
return microtime( true );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* resume an individual timer
|
||
|
* @param $name
|
||
|
*/
|
||
|
function __resumeTimer( $name ) {
|
||
|
$this->trace .= "resume $name\n";
|
||
|
$this->startTime[$name] = $this->getMicroTime();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* suspend an individual timer
|
||
|
* @param $name
|
||
|
*/
|
||
|
function __suspendTimer( $name ) {
|
||
|
$this->trace .= "suspend $name\n";
|
||
|
$this->endTime[$name] = $this->getMicroTime();
|
||
|
if ( !array_key_exists( $name, $this->running ) ) {
|
||
|
$this->running[$name] = $this->elapsedTime( $name );
|
||
|
} else {
|
||
|
$this->running[$name] += $this->elapsedTime( $name );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $name
|
||
|
*/
|
||
|
function profiler_start( $name ) {
|
||
|
if ( array_key_exists( "midcom_profiler", $GLOBALS ) ) {
|
||
|
$GLOBALS["midcom_profiler"]->startTimer( $name );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param $name
|
||
|
*/
|
||
|
function profiler_stop( $name ) {
|
||
|
if ( array_key_exists( "midcom_profiler", $GLOBALS ) ) {
|
||
|
$GLOBALS["midcom_profiler"]->stopTimer( $name );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
?>
|