From 58db3531c77ade3674910e8fd3f4e6a7ca507e86 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 9 Dec 2020 22:24:31 +0000 Subject: [PATCH] Use hrtime() for collecting timings this allows nanosecond resolution and generally better accuracy than microtime(), which is subject to floating-point errors. --- src/timings/TimingsHandler.php | 21 ++++++++++----------- src/timings/TimingsRecord.php | 14 +++++++------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/timings/TimingsHandler.php b/src/timings/TimingsHandler.php index 6fc07adf8..eb7d402cb 100644 --- a/src/timings/TimingsHandler.php +++ b/src/timings/TimingsHandler.php @@ -27,14 +27,13 @@ use pocketmine\entity\Living; use pocketmine\Server; use function count; use function fwrite; -use function microtime; -use function round; +use function hrtime; use const PHP_EOL; class TimingsHandler{ /** @var bool */ private static $enabled = false; - /** @var float */ + /** @var int */ private static $timingStart = 0; /** @@ -53,7 +52,7 @@ class TimingsHandler{ $avg = $time / $count; - fwrite($fp, " " . $timings->getName() . " Time: " . round($time * 1000000000) . " Count: " . $count . " Avg: " . round($avg * 1000000000) . " Violations: " . $timings->getViolations() . PHP_EOL); + fwrite($fp, " " . $timings->getName() . " Time: $time Count: " . $count . " Avg: $avg Violations: " . $timings->getViolations() . PHP_EOL); } fwrite($fp, "# Version " . Server::getInstance()->getVersion() . PHP_EOL); @@ -73,8 +72,8 @@ class TimingsHandler{ fwrite($fp, "# Entities " . $entities . PHP_EOL); fwrite($fp, "# LivingEntities " . $livingEntities . PHP_EOL); - $sampleTime = microtime(true) - self::$timingStart; - fwrite($fp, "Sample time " . round($sampleTime * 1000000000) . " (" . $sampleTime . "s)" . PHP_EOL); + $sampleTime = hrtime(true) - self::$timingStart; + fwrite($fp, "Sample time $sampleTime (" . ($sampleTime / 1000000000) . "s)" . PHP_EOL); } public static function isEnabled() : bool{ @@ -93,7 +92,7 @@ class TimingsHandler{ public static function reload() : void{ TimingsRecord::clearRecords(); if(self::$enabled){ - self::$timingStart = microtime(true); + self::$timingStart = hrtime(true); } } @@ -123,11 +122,11 @@ class TimingsHandler{ public function startTiming() : void{ if(self::$enabled){ - $this->internalStartTiming(microtime(true)); + $this->internalStartTiming(hrtime(true)); } } - private function internalStartTiming(float $now) : void{ + private function internalStartTiming(int $now) : void{ if(++$this->timingDepth === 1){ if($this->record === null){ $this->record = new TimingsRecord($this); @@ -141,11 +140,11 @@ class TimingsHandler{ public function stopTiming() : void{ if(self::$enabled){ - $this->internalStopTiming(microtime(true)); + $this->internalStopTiming(hrtime(true)); } } - private function internalStopTiming(float $now) : void{ + private function internalStopTiming(int $now) : void{ if($this->timingDepth === 0){ //TODO: it would be nice to bail here, but since we'd have to track timing depth across resets //and enable/disable, it would have a performance impact. Therefore, considering the limited diff --git a/src/timings/TimingsRecord.php b/src/timings/TimingsRecord.php index 106ad3772..1150e55f4 100644 --- a/src/timings/TimingsRecord.php +++ b/src/timings/TimingsRecord.php @@ -54,8 +54,8 @@ final class TimingsRecord{ public static function tick(bool $measure = true) : void{ if($measure){ foreach(self::$records as $record){ - if($record->curTickTotal > 0.05){ - $record->violations += (int) round($record->curTickTotal / 0.05); + if($record->curTickTotal > 50000000){ + $record->violations += (int) round($record->curTickTotal / 50000000); } $record->curTickTotal = 0; $record->curCount = 0; @@ -78,11 +78,11 @@ final class TimingsRecord{ private $count = 0; /** @var int */ private $curCount = 0; - /** @var float */ + /** @var int */ private $start = 0; - /** @var float */ + /** @var int */ private $totalTime = 0; - /** @var float */ + /** @var int */ private $curTickTotal = 0; /** @var int */ private $violations = 0; @@ -107,11 +107,11 @@ final class TimingsRecord{ public function getViolations() : int{ return $this->violations; } - public function startTiming(float $now) : void{ + public function startTiming(int $now) : void{ $this->start = $now; } - public function stopTiming(float $now) : void{ + public function stopTiming(int $now) : void{ if($this->start == 0){ return; }