Skip to content

Instantly share code, notes, and snippets.

@adawolfa adawolfa/tps_meter.php
Last active Nov 8, 2019

Embed
What would you like to do?
Ticks per second meter for ReactPHP
<?php
declare(strict_types=1);
/**
* Reports ticks per second to STDERR.
*
* Note that this function saturates event loop significantly with precision of zero and slows it down quite a lot,
* as it registers a callback on each tick. Because the event loop will be unable to sleep, CPU time consumption
* raises up to 100 %.
*
* This is for debugging purposes only, obviously. PHP >= 7.1.
*
* @author Adam Klvač <adam@klva.cz>
*
* @param React\EventLoop\LoopInterface $loop
* @param float $frequency How often should data be reported (snapshot time).
* @param float $precision Interval between individual ticks (higher means lower precision but also less overhead).
* @param bool $inline Should the statistics be updated in a single line?
* Set to false if your application prints anything.
*/
function tps_meter(React\EventLoop\LoopInterface $loop, float $frequency = 1.0, float $precision = .0, bool $inline = true): void
{
$microtime = function_exists('hrtime')
? function(): float {
return hrtime(true) / 10e9;
}
: function(): float {
return microtime(true);
};
$data = [
'last' => null,
'next' => null,
'count' => 0,
'sum' => null,
'min' => null,
'max' => null,
];
$collector = function() use(&$collector, &$data, $loop, $microtime, $frequency, $precision, $inline): void {
if ($precision === .0) {
$loop->futureTick($collector);
}
if ($data['last'] === null) {
$data['last'] = $microtime();
$data['next'] = $data['last'] + $frequency;
return;
}
$time = $microtime();
$msec = $time - $data['last'];
$data['last'] = $time;
if ($data['count'] === 0) {
$data['min'] = $msec;
$data['max'] = $msec;
$data['sum'] = .0;
}
$data['count']++;
$data['sum'] += $msec;
if ($msec < $data['min']) {
$data['min'] = $msec;
}
if ($msec > $data['max']) {
$data['max'] = $msec;
}
if ($data['next'] < $time) {
fprintf(
STDERR, ($inline ? "\r" : '') . "ticks: % 5d min: %.8f max: %.8f avg: %.8f sec: %.8f" . ($inline ? '' : "\n"),
$data['count'], $data['min'], $data['max'], $data['sum'] / $data['count'], $time - $data['next'] + $frequency
);
$data['count'] = 0;
$data['next'] = $time + $frequency;
}
};
if ($precision === .0) {
$loop->futureTick($collector);
} else {
$loop->addPeriodicTimer($precision, $collector);
}
}
<?php
$loop = React\EventLoop\Factory::create();
// Shows and updates a status line:
tps_meter($loop);
$loop->run();
// OUTPUT
// [CR] ticks: 79779 min: 0.00001192 max: 0.00021696 avg: 0.00001253 sec: 1.00001001
// Prints a line each second:
tps_meter($loop, 1.0, .0, false);
$loop->run();
// OUTPUT
// ticks: 80285 min: 0.00001192 max: 0.00006294 avg: 0.00001246 sec: 1.00001001 [LF]
// ticks: 80347 min: 0.00001192 max: 0.00071001 avg: 0.00001245 sec: 1.00001097 [LF]
// ticks: 80112 min: 0.00001192 max: 0.00017595 avg: 0.00001248 sec: 1.00000691 [LF]
// ticks: 80120 min: 0.00001192 max: 0.00024796 avg: 0.00001248 sec: 1.00000596 [LF]
// ticks: 80004 min: 0.00001192 max: 0.00023699 avg: 0.00001250 sec: 1.00000906 [LF]
// Prints a line each 5 seconds, do just 100 ticks per second:
tps_meter($loop, 5.0, 1 / 100, false);
$loop->run();
// OUTPUT
// ticks: 455 min: 0.00924492 max: 0.01210093 avg: 0.01100267 sec: 5.00621700 [LF]
// ticks: 455 min: 0.00928307 max: 0.01234078 avg: 0.01099965 sec: 5.00484109 [LF]
// ticks: 455 min: 0.00939584 max: 0.01222205 avg: 0.01100143 sec: 5.00565100 [LF]
// ticks: 455 min: 0.00934696 max: 0.01225710 avg: 0.01099885 sec: 5.00447607 [LF]
// ticks: 455 min: 0.00902700 max: 0.01219988 avg: 0.01099984 sec: 5.00492692 [LF]
// If there's a blocking call somewhere, event loop will lag, which causes
// 'max' and 'avg' time to raise and 'ticks' count will decrease accordingly:
// ticks: 994 min: 0.00001287 max: 0.00225091 avg: 0.00100787 sec: 1.00182605
// ticks: 989 min: 0.00001287 max: 0.00236011 avg: 0.00101126 sec: 1.00013494
// ticks: 498 min: 0.00001407 max: 0.50023699 avg: 0.00200977 sec: 1.00086308
// ^^^ ^^^^^^^^^^ ^^^^^^^^^^
// ticks: 993 min: 0.00001311 max: 0.00227499 avg: 0.00100721 sec: 1.00016093
// ticks: 994 min: 0.00001287 max: 0.00224185 avg: 0.00100729 sec: 1.00124216
// ticks: 992 min: 0.00001311 max: 0.00245500 avg: 0.00100880 sec: 1.00073290
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.