Scripts

PHP Timer Object

Er zijn veel manieren om de parsetime van je script te bepalen. Ik vind echter het mooiste om gebruik te maken van een object. Ik heb dan ook een timer object geschreven, welke een aantal functies bezit om de parsetime van je script te meten. De meeste functies zullen voor zichzelf wijzen. De timer wordt automatisch gestart bij het initieren van het object. Het object heeft de mogelijkheid om data naar een file te loggen. Dit bestand zal voor elke unieke url een nieuwe regel maken. Deze regel heeft de volgende structuur: URL : AANTAL REQUESTS : GEMIDDELDE PARSETIME PER REQUEST Ik liep echter ook tegen het probleem aan dat je soms wilt weten hoe lang je script over bepaalde stukken doet. Hiervoor heb ik een extra object ontwikkeld dat gebruik maakt van de DIV_TIMER class. Dit tweede object verzameld eigenlijk wat data en kan dat leuk laten zien, niet echt bijzonder, wel handig Changelog + 2007-07-23: Functie toegevoegd om filename te setten, filename bij initializeren null. Tevens de functie parse vervallen en vervangen door parse_as_htmlcomment. Ook de mogelijkheid om alle punten op te vragen als array is nu mogelijk.

php-timer-object
[b]voorbeeld.php[/b]
[code]
<?
include('TIMER.class.php');

// Creer het timer object
$oTimer = new DIV_TIMER('log.txt');

// Creer ook een performance meter, gewoon als voorbeeld
$oPerfmeter = new DIV_PERFORMANCE_METER();

// doe wat dingen
$j = 0;
for($i=0; $i<100; $i++)
{
	$j = $j + $i * 2;
	if($i%10 == 0)
	{ 
		echo 'Tien rondjes gedaan  j = '.$j.'<br />'."\r\n";
		$oPerfmeter->add_point('Tijd na ronde '.$i);
	}
}

// Print de tijd die je script erover gedaan heeft:
$oTimer->stop();
echo $oTimer->get_time();

// Leuk om te zien hoelang iedere ronde duurde?
//  dit wordt nog als html commentaar geplaatst. Staat dus automatisch in je source
// Niet erg netjes, moet nog aangepast worden.
echo '<br />Voor ronde tijden, zie de source!<br/>'."\r\n";
echo '<a href="log.txt">klik hier voor de log</a>';

$oPerfmeter->parse();

?>
[/code]

[b]TIMER.class.php[/b]
[code]
<?
class DIV_TIMER
{
	var $_fStartTime;
	var $_fEndTime;
	var $_blnFinished = false;
	var $_strFile;

	/**
	 * Constructor. Autostart the timer.
	 *
	 */
	function DIV_TIMER($strFile = null)
	{
		$this->_strFile = $strFile;
		$this->start();
	}

	/**
	 * Set the filename to save statistics in
	 *
	 * @param unknown_type $strFile
	 */
	function set_file($strFile)
	{
		$this->_strFile = $strFile;
	}
	
	/**
	 * Start the internal timer. Can also be used for a restart
	 *
	 */
	function start()
	{
		$this->_fStartTime = $this->microtime_as_float();
		$this->_blnFinished = false;
	}

	/**
	 * Can be used static
	 *
	 * @return unknown
	 */
	function microtime_as_float()
	{
	    list($usec, $sec) = explode(" ", microtime());
	    return ((float)$usec + (float)$sec);
	}

	/**
	 * Stop the timer. The stoptime will be remembered.
	 *  If a file isset, then the time will be saved.
	 *
	 */
	function stop()
	{
		if(!$this->_blnFinished)
		{
			$this->_fEndTime = $this->microtime_as_float();
			$this->_blnFinished = true;
			
			if(!is_null($this->_strFile))
			{
				$strPerfData = '';
				$strMyFilename = $_SERVER['REQUEST_URI'];
				$fTimeDiff = ($this->_fEndTime - $this->_fStartTime);
				
				if(file_exists($this->_strFile) && filesize($this->_strFile))
				{
					$f = fopen($this->_strFile, "r");
					$strPerfData = fread($f, filesize($this->_strFile));
					fclose($f);
				}
				
				if(strpos($strPerfData, $strMyFilename) !== false)
				{
					$iLinestart = strpos($strPerfData, $strMyFilename);
					$iLineend = strpos($strPerfData, ';', $iLinestart);
					
					$strLineData = substr($strPerfData, $iLinestart, $iLineend-$iLinestart);
					list($strFile, $iCount, $fAvgTime) = explode(':', $strLineData);
					$iCount = intval($iCount) + 1;
					$fAvgTime = (floatval($fAvgTime) * ($iCount-1) + $fTimeDiff) / $iCount;
					
					$strPerfData = substr_replace($strPerfData, $strMyFilename.':'.$iCount.':'.$fAvgTime, $iLinestart, $iLineend-$iLinestart);
				}
				else 
				{
					$strPerfData .= $strMyFilename.':1:'.$fTimeDiff.";\r\n";
					
				}
				
				$f = fopen($this->_strFile, "w+");
				fwrite($f, $strPerfData);
				fclose($f);
			}
		}
	}

	/**
	 * Stop the timer and reset the data
	 *
	 */
	function reset()
	{
		$this->_fStartTime = 0;
		$this->_fEndTime=0;
		$this->_blnFinished = true;
	}

	/**
	 * Get the time in seconds
	 *
	 * @return timing time in seconds
	 */
	function get_time()
	{
		if($this->_blnFinished)
			return ($this->_fEndTime - $this->_fStartTime);
		else return ($this->microtime_as_float() - $this->_fStartTime);
	}
}

class DIV_PERFORMANCE_METER 
{
	var $_oTimer;
	var $_arrAssocPoints = array();

	/**
	 * Constructor
	 *
	 * @return DIV_PERFORMANCE_METER
	 */
	function DIV_PERFORMANCE_METER()
	{
		$this->_oTimer = new DIV_TIMER();
	}

	/**
	 * Add a save point to the performance meter. Name it as you like, the name has to be unique, otherwise it will be overwritten
	 *
	 * @param unknown_type $strName
	 */
	function add_point($strName)
	{
		$this->_arrAssocPoints[$strName] = $this->_oTimer->get_time();
	}

	/**
	 * Deprecated function. Now named parse_as_htmlcomment
	 *
	 */
	function parse()
	{
		$this->parse_as_htmlcomment();
	}
	
	/**
	 * Output the data in a htmlcomment element
	 *
	 */
	function parse_as_htmlcomment()
	{
		$strComment = '<!--'."\n";
		foreach($this->_arrAssocPoints as $key=>$value)
			$strComment .= $key.':'."\t".$value."\n";
			
		$strComment .= '-->';
		
		echo $strComment;
	}
	
	/**
	 * Get an array with all the points, the array is associative. The key of every element is equal to the name passed with add_point()
	 *
	 * @return unknown
	 */
	function get_timedata()
	{
		return $this->_arrPoints;
	}
	
}
?>[/code]

Reacties

0
Nog geen reacties.