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

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

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

Post 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);
?>
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post 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.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post 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;
    }
?>
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post 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);
    }
}
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post 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:
User avatar
vigge89
Forum Regular
Posts: 875
Joined: Wed Jul 30, 2003 3:29 am
Location: Sweden

Post 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).
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post 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.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

I am an object oriented dude, so I always favor objects myself. Though I like what you did with that last function.
Post Reply