Rendertime
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.
<?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');
}
}
Please register or sign in to comment