Skip to main content
2 of 4
edited tags
200_success
  • 145.6k
  • 22
  • 191
  • 481

Rewrote my benchmark/timer library

I created a timer library called PHPBenchTime a few years ago, and decided to rewrite it last week.

This new version is meant to add in missing functionality (pause/unpause) as well as expand on the reporting system (so now everything is a lap and has finer details). Additionally, the rewrite was aimed at cleaning the code and making it easier to follow the flow of information/expand on the library in the future (by making $laps the primary data point).

namespace PHPBenchTime;

class Timer {

    /**
     * Time that $this->start() was called
     *
     * @var int
     */
    private $startTime = 0;

    /**
     * Time that $this->end() was called
     *
     * @var int
     */
    private $endTime = 0;

    /**
     * Total time spent in pause
     *
     * @var int
     */
    private $totalPauseTime = 0;

    /**
     * Time spent in pause
     *
     * @var int
     */
    private $pauseTime = 0;

    /**
     * Difference between $this->startTime and $this->endTime
     *
     * @var int
     */
    private $totalTime = 0;

    /**
     * Contains all laps
     *
     * @var array
     */
    private $laps = array();

    /**
     * Is the timer currently actively running?
     *
     * @var bool
     */
    private $isRunning = false;

    /**
     * Determine if we are paused
     *
     * @var bool
     */
    private $isPaused = false;

    /**
     * Keeps track of what lap we are currently on
     *
     * @var int
     */
    private $lapCount = 0;

    /**
     * Class constructor
     */
    public function __construct() {
        $this->reset();
    }

    /**
     * Resets the timers, laps and summary
     */
    public function reset() {
        $this->startTime = 0;
        $this->endTime   = 0;
        $this->pauseTime = 0;
        $this->totalTime = 0;
        $this->laps      = array();
        $this->isRunning = false;
        $this->isPaused  = false;
        $this->lapCount  = 0;
    }

    /**
     * Starts the timer
     */
    public function start() {
        $this->setRunningPaused( true, false );

        # Set the start time
        $this->startTime = $this->getCurrentTime();

        # Create a lap with this start time
        $this->lap( "start" );
    }

    /**
     * Ends the timer
     */
    public function end() {
        $this->setRunningPaused( false, true );

        # Set the end time
        $this->endTime = $this->getCurrentTime();

        # end the last lap
        $this->endLap();

        return $this->summary();
    }

    /**
     * Creates a new lap in lap array property
     */
    public function lap( $name = null ) {
        $lapTime = $this->getCurrentTime();

        # end the last lap
        $this->endLap();

        # Create new lap
        $this->laps[] = array(
            "name"  => ( $name ? $name : $this->lapCount ),
            "start" => $lapTime,
            "end"   => -1,
            "total" => -1,
        );

        $this->lapCount += 1;
    }

    /**
     * Returns a summary of all timer activity so far
     *
     * @return array
     */
    public function summary() {
        $this->totalTime = $this->endTime - $this->startTime;

        $summary = array(
            'running' => ( $this->isRunning === true ? "true" : "false" ),
            'start'   => $this->startTime,
            'end'     => $this->endTime,
            'total'   => $this->totalTime,
            'paused'  => $this->totalPauseTime,
            'laps'    => $this->laps
        );

        return $summary;
    }

    /**
     * Initiates a pause in the timer
     */
    public function pause() {
        $this->setRunningPaused( false, true );
        $this->pauseTime = $this->getCurrentTime();
    }

    /**
     * Cancels the pause previously set
     */
    public function unPause() {
        $this->setRunningPaused( true, false );
        $this->totalPauseTime = $this->getCurrentTime() - $this->pauseTime;
        $this->pauseTime      = 0;
    }

    /**
     * Assign end and total times to the previous lap
     */
    private function endLap() {
        $lapCount = count( $this->laps ) - 1;
        if ( count( $this->laps ) > 0 ) {
            $this->laps[$lapCount]['end']   = $this->getCurrentTime();
            $this->laps[$lapCount]['total'] = $this->laps[$lapCount]['end'] - $this->laps[$lapCount]['start'];
        }
    }

    /**
     * Handles isRunning and isPaused
     *
     * @param $running
     * @param $paused
     */
    private function setRunningPaused( $running, $paused ) {
        $this->isRunning = is_bool( $running ) ? $running : false;
        $this->isPaused  = is_bool( $paused ) ? $paused : false;
    }

    /**
     * Returns the current time
     *
     * @return float
     */
    private function getCurrentTime() {
        return microtime( true );
    }
}

Same code, without comments:

namespace PHPBenchTime;

class Timer {
    private $startTime = 0;
    private $endTime = 0;
    private $totalPauseTime = 0;
    private $pauseTime = 0;
    private $totalTime = 0;
    private $laps = array();
    private $isRunning = false;
    private $isPaused = false;
    private $lapCount = 0;

    public function __construct() {
        $this->reset();
    }

    public function reset() {
        $this->startTime = 0;
        $this->endTime   = 0;
        $this->pauseTime = 0;
        $this->totalTime = 0;
        $this->laps      = array();
        $this->isRunning = false;
        $this->isPaused  = false;
        $this->lapCount  = 0;
    }

    public function start() {
        $this->setRunningPaused( true, false );
        $this->startTime = $this->getCurrentTime();
        $this->lap( "start" );
    }

    public function end() {
        $this->setRunningPaused( false, true );
        $this->endTime = $this->getCurrentTime();
        $this->endLap();
        return $this->summary();
    }

    public function lap( $name = null ) {
        $lapTime = $this->getCurrentTime();
        $this->endLap();

        $this->laps[] = array(
            "name"  => ( $name ? $name : $this->lapCount ),
            "start" => $lapTime,
            "end"   => -1,
            "total" => -1,
        );

        $this->lapCount += 1;
    }

    public function summary() {
        $this->totalTime = $this->endTime - $this->startTime;

        $summary = array(
            'running' => ( $this->isRunning === true ? "true" : "false" ),
            'start'   => $this->startTime,
            'end'     => $this->endTime,
            'total'   => $this->totalTime,
            'paused'  => $this->totalPauseTime,
            'laps'    => $this->laps
        );

        return $summary;
    }

    public function pause() {
        $this->setRunningPaused( false, true );
        $this->pauseTime = $this->getCurrentTime();
    }

    public function unPause() {
        $this->setRunningPaused( true, false );
        $this->totalPauseTime = $this->getCurrentTime() - $this->pauseTime;
        $this->pauseTime      = 0;
    }

    private function endLap() {
        $lapCount = count( $this->laps ) - 1;
        if ( count( $this->laps ) > 0 ) {
            $this->laps[$lapCount]['end']   = $this->getCurrentTime();
            $this->laps[$lapCount]['total'] = $this->laps[$lapCount]['end'] - $this->laps[$lapCount]['start'];
        }
    }

    private function setRunningPaused( $running, $paused ) {
        $this->isRunning = is_bool( $running ) ? $running : false;
        $this->isPaused  = is_bool( $paused ) ? $paused : false;
    }

    private function getCurrentTime() {
        return microtime( true );
    }
}

Usage and expected result:

use PHPBenchTime\Timer;
$T = new Timer;
$T->start();
sleep(1);
$T->lap();
sleep(2);
$T->lap();

print_r($T->end());

Array
(
    [running] => false
    [start] => 1406563433.8282
    [end] => 1406563436.8289
    [total] => 3.0007529258728
    [paused] => 0
    [laps] => Array
        (
            [0] => Array
                (
                    [name] => start
                    [start] => 1406563433.8282
                    [end] => 1406563434.8285
                    [total] => 1.0003159046173
                )

            [1] => Array
                (
                    [name] => 1
                    [start] => 1406563434.8285
                    [end] => 1406563436.8289
                    [total] => 2.0004169940948
                )

            [2] => Array
                (
                    [name] => 2
                    [start] => 1406563436.8289
                    [end] => 1406563436.8289
                    [total] => 7.7962875366211E-5
                )

        )

)
jsanc623
  • 2.9k
  • 16
  • 22