// SPDX-License-Identifier: GPL-3.0-or-later
/**
* Icinga\Application\Benchmark class
*/
namespace Icinga\Application;
use Icinga\Util\Format;
/**
* This class provides a simple and lightweight benchmark class
*
*
* Benchmark::measure('Program started');
* // ...do something...
* Benchmark::measure('Task finieshed');
* Benchmark::dump();
*
*/
class Benchmark
{
const TIME = 0x01;
const MEMORY = 0x02;
protected static $instance;
protected $start;
protected $measures = array();
/**
* Add a measurement to your benchmark
*
* The same identifier can also be used multiple times
*
* @param string A comment identifying the current measurement
* @return void
*/
public static function measure($message)
{
self::getInstance()->measures[] = (object) array(
'timestamp' => microtime(true),
'memory_real' => memory_get_usage(true),
'memory' => memory_get_usage(),
'message' => $message
);
}
/**
* Throws all measurements away
*
* This empties your measurement table and allows you to restart your
* benchmark from scratch
*
* @return void
*/
public static function reset()
{
self::$instance = null;
}
/**
* Rerieve benchmark start time
*
* This will give you the timestamp of your first measurement
*
* @return float
*/
public static function getStartTime()
{
return self::getInstance()->start;
}
/**
* Dump benchmark data
*
* Will dump a text table if running on CLI and a simple HTML table
* otherwise. Use Benchmark::TIME and Benchmark::MEMORY to choose whether
* you prefer to show either time or memory or both in your output
*
* @param ?int $what Whether to get time and/or memory summary
*/
public static function dump($what = null)
{
if (Icinga::app()->isCli()) {
echo self::renderToText($what);
} else {
echo self::renderToHtml($what);
}
}
/**
* Render benchmark data to a simple text table
*
* Use Benchmark::TIME and Icinga::MEMORY to choose whether you prefer to
* show either time or memory or both in your output
*
* @param ?int $what Whether to get time and/or memory summary
* @return string
*/
public static function renderToText($what = null)
{
$data = self::prepareDataForRendering($what);
$sep = '+';
$title = '|';
foreach ($data->columns as & $col) {
$col->format = ' %'
. ($col->align === 'right' ? '' : '-')
. $col->maxlen . 's |';
$sep .= str_repeat('-', $col->maxlen) . '--+';
$title .= sprintf($col->format, $col->title);
}
$out = $sep . "\n" . $title . "\n" . $sep . "\n";
foreach ($data->rows as & $row) {
$r = '|';
foreach ($data->columns as $key => & $col) {
$r .= sprintf($col->format, $row[$key]);
}
$out .= $r . "\n";
}
$out .= $sep . "\n";
return $out;
}
/**
* Render benchmark data to a simple HTML table
*
* Use Benchmark::TIME and Benchmark::MEMORY to choose whether you prefer
* to show either time or memory or both in your output
*
* @param ?int $what Whether to get time and/or memory summary
*
* @return string
*/
public static function renderToHtml($what = null)
{
$data = self::prepareDataForRendering($what);
// TODO: Move formatting to CSS file
$html = '
| %s | ', $col->align, htmlspecialchars($col->title) ); } $html .= "
| %s | ', $col->align, $row[$key] ); } $html .= "