Skip to content
Snippets Groups Projects

Rendertime

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Thomas Flori

    Class Rendertime

    This helper class is for uncomplicated profiling of executed code. Just place anywhere in your code:

    Rendertime::start('key');
    // your code
    Rendertime::end('key');

    You can start multiple keys at the same time. The time is recorded for each key separately.

    To receive the rendertime statistics, just call: Rendertime::getRendertime().

    If there is interest I can deploy that to packagist.

    Edited
    Rendertime.php 3.18 KiB
    <?php
    
    /**
     * Class Rendertime
     *
     * This helper class is for uncomplicated profiling of executed code.
     * Just place anywhere in your code:
     * ```php
     * Rendertime::start('key');
     * // your code
     * Rendertime::end('key');
     * ```
     *
     * You can start multiple keys at the same time. The time is recorded for each key separately.
     *
     *  To receive the rendertime statistics, just call: `Rendertime::getRendertime()`.
     */
    class Rendertime
    {
        private $lastCall;
        private $stack = [];
        private $renderTimes = [];
    
        // singleton instance
        /** @var Rendertime */
        private static $instance = null;
    
        private function __construct(float $start = 0)
        {
            $this->lastCall = ($start > 0) ? $start : microtime(true);
            $this->stack[] = ['other', 0];
        }
    
        private function __clone()
        {
        }
    
        /** @return Rendertime */
        public static function getInstance($fStartTime = 0)
        {
            if (null === self::$instance) {
                self::$instance = new self($fStartTime);
            }
            return self::$instance;
        }
    
        public static function __callStatic($name, $arguments)
        {
            return call_user_func_array([self::getInstance(), $name], $arguments);
        }
    
        private function start(string $key)
        {
            $now = microtime(true);
            $past = $now - $this->lastCall;
            $currentItem = &$this->stack[count($this->stack) - 1];
            $currentItem[1] += $past;
    
            $this->stack[] = [$key, 0];
            $this->lastCall = microtime(true);
            return true;
        }
    
        private function end(string $key)
        {
            $now = microtime(true);
            if (!in_array($key, array_column(array_reverse($this->stack), 0))) {
                return false;
            }
    
            $past = $now - $this->lastCall;
            do {
                $this->recordTime($past);
                [$currentKey] = array_pop($this->stack);
                $past = 0;
            } while ($key != $currentKey);
    
            $this->lastCall = microtime(true);
            return true;
        }
    
        private function recordTime(float $past)
        {
            [$currentKey, $value] = $this->stack[count($this->stack) - 1];
            if (!isset($this->renderTimes[$currentKey])) {
                $this->renderTimes[$currentKey] = [];
            }
            $this->renderTimes[$currentKey][] = $value + $past;
        }
    
        private function getRendertime(string $key = null): array
        {
            $this->recordTime(microtime(true) - $this->lastCall);
            $this->lastCall = microtime(true);
    
            if (is_null($key)) {
                $renderTimes = array_map([$this, 'buildStatistics'], $this->renderTimes);
                $renderTimes['overall'] = $this->buildStatistics(array_merge(...array_values($this->renderTimes)));
                return $renderTimes;
            } else {
                return $this->buildStatistics($this->renderTimes[$key] ?? []);
            }
        }
    
        private function buildStatistics(array $times): array
        {
            if (empty($times)) {
                return ['count' => 0, 'min' => 0, 'max' => 0, 'avg' => 0, 'sum' => 0];
            }
    
            $count = count($times);
            $min = min($times);
            $max = max($times);
            $sum = array_sum($times);
            $avg = $sum / $count;
            return compact('count', 'min', 'max', 'avg', 'sum');
        }
    }
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment