Page 1 of 1

On the heels of Pickle's timer class...

Posted: Fri Dec 21, 2007 6:12 pm
by RobertGonzalez
Thought I'd throw mine out. I didn't want to hijack his thread. This was coded for my framework I am developing.

Notes:
  • This is a PHP 5 class. It will not work in a PHP 4 environment. No, I will not port it. But you are more than welcome to if you want.
  • I have considered adding a stopAndRestart method, but have not needed it as of yet so have not put that in (though it is fairly trivial to do).

Code: Select all

<?php
/**
 * Padlock - PHP Application Developers Library and Opensource Code Kit
 * 
 * @category Padlock
 * @package Padlock
 * @author Robert Gonzalez <robert@everah.com>
 * @copyright Copyright (c) 2007, Everah Media Services.
 * @license http://creativecommons.org/licenses/by/3.0/ Creative Commons Attribution License 3.0 
 * @version $Id: Timer.php 93 2007-12-11 14:59:55Z robert $
 */
/**
 * Padlock Timer - Manages timing of process
 * 
 * This class handles just about all aspects of keeping time using a method 
 * similar to microtime(true) - microtime(true).
 * 
 * Usage:
 * <code><?php
 * $timer = Padlock::getObject('Padlock_Timer');
 * $timer->startTimer('page');
 * $timer->startTimer('hello');
 * sleep(3);
 * echo 'Hello World.';
 * $timer->stopTimer('hello');
 * echo 'Total time for hello was ' . $timer->getTotalTime('hello');
 * // more code
 * echo 'Page execution time was ' . $timer->getTotalTime('page') . ' seconds';
 * ?></code>
 * 
 * @author Robert Gonzalez <robert@everah.com>
 * @category Padlock
 * @package Padlock
 * @version @package_version@
 */
class Padlock_Timer {
     /**
      * Accuracy measurement for decimal places
      * 
      * @access protected
      * @var integer
      */
     protected $accuracy = 5;
     
    /**
     * The array of timers used by the class
     * 
     * @access private
     * @var array
     */
    private $timers = array();
        
    /**
     * The class constructor
     * 
     * Note that this does not do any timing at all upon instantiation. This merely
     * sets the object. It can very easily be coded to start a timer upon
     * instantiation.
     * 
     * @access private
     */
    public function __construct() {
        // To start a timer upon construction, simply add an argument to the 
        // constructor called $name. Default that to 'default' then start a new
        // timer based on that name. Something a la
        // $this->startTimer($name);
    }
    
    /**
     * Sets the accuracy measurement for the rendered float value of the timer
     * 
     * @access public
     * @param integer $length
     */
    public function setAccuracy($length = 5) {
        if (is_numeric($length)) {
            $this->accuracy = intval($length);
        }
    }
    
    /**
     * Timer starter for entry $name
     * 
     * @access public
     * @param string $name
     */
    public function startTimer($name = 'default') {
        if (!isset($this->timers[$name]['start'])) {
            $this->timers[$name]['start'] = microtime(true);
        }
    }
    
    /**
     * Timer stopper for entry $name
     * 
     * @access public
     * @param string $name
     */
    public function stopTimer($name = 'default') {
        if (!isset($this->timers[$name]['stop'])) {
            $this->timers[$name]['stop'] = microtime(true);
        }
    }
    
    /**
     * Timer totalizer for entry $name
     * 
     * @access public
     * @param string $name
     */
    public function totalTime($name = 'default') {
        if (!isset($this->timers[$name]['start'])) {
            return (bool) false;
        }
        
        if (isset($this->timers[$name]['stop'])) {
            $stop_time = $this->timers[$name]['stop'];
        } else {
            $stop_time = $this->stopTimer($name);
        }
        
        // do the big numbers first so the small ones aren't lost
        $this->timers[$name]['total'] = $stop_time - $this->timers[$name]['start'];
    }
    
    /**
     * Timer total fetcher for entry $name
     * 
     * @access public
     * @param string $name
     * @return float The time, in milliseconds, of execution or false on failure
     */
    public function getTotalTime($name = 'default') {
        if (!isset($this->timers[$name]['start'])) {
            return (bool) false;
        }
        
        if (!isset($this->timers[$name]['total'])) {
            $this->totalTime($name);
        }
        
        return sprintf("%.{$this->accuracy}f", $this->timers[$name]['total']);
    }
}

/********************************************************************
 * TESTS
 * 
 * Note: Setting an accuracy is not required. It is only shown as 
 * an example that is can be done, and if it is, it should be done 
 * after the time calculcations so that the timing process is not
 * altered.
 *******************************************************************/
// A single timed event
/*
$t = new Padlock_Timer();
$t->startTimer();
sleep(2);
$t->stopTimer();
$t->setAccuracy(7);
echo $t->getTotalTime() . "\n";
$t->setAccuracy(12);
echo $t->getTotalTime() ."\n";
*/

// Multiple events
$t1 = 'billy';
$t2 = 'bobby';
$t = new Padlock_Timer();
$t->startTimer($t1);
$t->startTimer($t2);
sleep(2);
$t->stopTimer($t2);
sleep(3);
$t->stopTimer($t1);
$t->setAccuracy(7);
echo $t->getTotalTime($t1) . "\n";
echo $t->getTotalTime($t2) . "\n";
$t->setAccuracy(12);
echo $t->getTotalTime($t1) ."\n";
echo $t->getTotalTime($t2);
?>

Posted: Sun Dec 23, 2007 10:06 pm
by Kieran Huggins
I just wanted to join the party with my simple timer:

Code: Select all

class Timer{
	protected $startTime;

	public function __construct(){
		$this->startTime = microtime(true);
	}
	
	public function __toString(){
		return (string)(microtime(true) - $this->startTime);
	}
}

//usage:

$timer = new Timer;
sleep(1);
echo $timer."<br/>";
sleep(1);
echo $timer."<br/>";
Each instance is a separate timer and starts automatically. Simply echo the object for the elapsed time in seconds.

It's not fancy like Everah's at all. No bells, no whistles, but I like it.

Who else has one? Let's get a big ol' thread going.

Posted: Sun Dec 23, 2007 11:01 pm
by RobertGonzalez
I was thinking about adding a toString overloader to mine. Something like:

Code: Select all

<?php
    /**
     * Echos out a dump of all timers currently in the timer object
     * 
     * NOTE: This will stop any running timer!
     * 
     * @access public
     * @return string Dump of all timers currently in the timer object
     */
    public function __toString() {
        // Create the string to return
        $return = '';

        // Grab the timers
        $timers = array_keys($this->timers);

        // Set times
        foreach ($timers as $timer) {
            $return .= $this->getTotalTime($timer) . "\n";
        }

        // Return it
        return $return;
    }
?>

Posted: Sun Dec 23, 2007 11:07 pm
by s.dot

Code: Select all

<?php

/**
 * This is a simple PHP5 timing class.
 * @author Scott Martin <smp_info[at]yahoo[dot]com>
 * @date Tuesday, November 6th, 2007
 */
class timer
{
    /**
     * This class member holds the microtime the class was instantiated.
     */
    private $_timeStart;

    /**
     * The timing starts once the class is initiated.
     * @access public
     */
    public function __construct() {
        $this->_timeStart = microtime(true);
    }

    /**
     * This method returns the floating precision of seconds since the class was
     * instantiated.
     * @param $round - The number of decimal places allowed.
     * @access public
     */
    public function getTime($round=5) {
        return round(microtime(true) - $this->_timeStart, $round);
    }
}

Posted: Mon Dec 24, 2007 2:41 am
by alex.barylski
Here is mine: http://www.codeproject.com/KB/cpp/profiler.aspx

Yikes...looks like I need to update that article and bump up the ratings...it's really bringing down my average...or I could just request to have it deleted. :lol:

Posted: Mon Dec 24, 2007 5:11 am
by vigge89
My copy-paste timer function for quick and dirty measuring, PHP5 only:

Code: Select all

function executionTime($reset = false, $digits = 3) {
	static $start;
	$now = microtime(true) * 1000;
	if (!isset($start)) $start = $now;
	$return = round($now - $start, $digits);
	if ($reset) $start = $now;
	return $return;
}
Drop the mutliplication by 1000 if you want it to measure in seconds and not milliseconds.
It's simple yet effective; call the function once to start the timer and then any later calls will return the elapsed time. Calling it with $reset set to true resets the timer after returning the current time (easy way of knowing how long a specific block of code took to execute).

Posted: Mon Dec 24, 2007 1:04 pm
by Kieran Huggins
A cross between vigge89 and Everah's:

Code: Select all

function timer($name='default',$reset=false){
	static $start = array();
	if(!isset($start[$name]) || $reset===true) $start[$name] = microtime(true);
	return microtime(true) - $start[$name];
}

// usage:

timer(); // starts a timer named "default"
timer('SQL Query'); // starts a timer named "SQL Query"
sleep(1);
echo timer('SQL query'); // echoes the SQL Query timer (@ 1 second)
sleep(1);
timer('SQL query',true); // resets the timer  (now @ 0 seconds)
echo timer(); // echoes the default timer (@ 2 seconds)
I think I still prefer instantiating timers as objects, even though it does pollute the variable space a little. Meh.

Posted: Mon Dec 24, 2007 3:06 pm
by RobertGonzalez
I am an object oriented dude, so I always favor objects myself. Though I like what you did with that last function.