From eae70963f61cf95e107cb99b5b337753fb5bcba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Wed, 9 Jan 2019 17:19:51 +0100 Subject: [PATCH 1/2] Use high resolution timer on PHP 7.3+ --- README.md | 17 +++++++++-------- src/LoopInterface.php | 8 ++++---- src/StreamSelectLoop.php | 9 +++++---- src/Timer/Timers.php | 9 +++++++-- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 1d25bdac..eb7bc195 100644 --- a/README.md +++ b/README.md @@ -182,13 +182,14 @@ It is commonly installed as part of many PHP distributions. If this extension is missing (or you're running on Windows), signal handling is not supported and throws a `BadMethodCallException` instead. -This event loop is known to rely on wall-clock time to schedule future -timers, because a monotonic time source is not available in PHP by default. +This event loop is known to rely on wall-clock time to schedule future timers +when using any version before PHP 7.3, because a monotonic time source is +only available as of PHP 7.3 (`hrtime()`). While this does not affect many common use cases, this is an important distinction for programs that rely on a high time precision or on systems that are subject to discontinuous time adjustments (time jumps). -This means that if you schedule a timer to trigger in 30s and then adjust -your system time forward by 20s, the timer may trigger in 10s. +This means that if you schedule a timer to trigger in 30s on PHP < 7.3 and +then adjust your system time forward by 20s, the timer may trigger in 10s. See also [`addTimer()`](#addtimer) for more details. #### ExtEventLoop @@ -360,8 +361,8 @@ same time (within its possible accuracy) is not guaranteed. This interface suggests that event loop implementations SHOULD use a monotonic time source if available. Given that a monotonic time source is -not available on PHP by default, event loop implementations MAY fall back -to using wall-clock time. +only available as of PHP 7.3 by default, event loop implementations MAY +fall back to using wall-clock time. While this does not affect many common use cases, this is an important distinction for programs that rely on a high time precision or on systems that are subject to discontinuous time adjustments (time jumps). @@ -433,8 +434,8 @@ same time (within its possible accuracy) is not guaranteed. This interface suggests that event loop implementations SHOULD use a monotonic time source if available. Given that a monotonic time source is -not available on PHP by default, event loop implementations MAY fall back -to using wall-clock time. +only available as of PHP 7.3 by default, event loop implementations MAY +fall back to using wall-clock time. While this does not affect many common use cases, this is an important distinction for programs that rely on a high time precision or on systems that are subject to discontinuous time adjustments (time jumps). diff --git a/src/LoopInterface.php b/src/LoopInterface.php index 1cc8640f..8146757a 100644 --- a/src/LoopInterface.php +++ b/src/LoopInterface.php @@ -185,8 +185,8 @@ public function removeWriteStream($stream); * * This interface suggests that event loop implementations SHOULD use a * monotonic time source if available. Given that a monotonic time source is - * not available on PHP by default, event loop implementations MAY fall back - * to using wall-clock time. + * only available as of PHP 7.3 by default, event loop implementations MAY + * fall back to using wall-clock time. * While this does not affect many common use cases, this is an important * distinction for programs that rely on a high time precision or on systems * that are subject to discontinuous time adjustments (time jumps). @@ -263,8 +263,8 @@ public function addTimer($interval, $callback); * * This interface suggests that event loop implementations SHOULD use a * monotonic time source if available. Given that a monotonic time source is - * not available on PHP by default, event loop implementations MAY fall back - * to using wall-clock time. + * only available as of PHP 7.3 by default, event loop implementations MAY + * fall back to using wall-clock time. * While this does not affect many common use cases, this is an important * distinction for programs that rely on a high time precision or on systems * that are subject to discontinuous time adjustments (time jumps). diff --git a/src/StreamSelectLoop.php b/src/StreamSelectLoop.php index 3e6ff07f..9867327e 100644 --- a/src/StreamSelectLoop.php +++ b/src/StreamSelectLoop.php @@ -38,13 +38,14 @@ * If this extension is missing (or you're running on Windows), signal handling is * not supported and throws a `BadMethodCallException` instead. * - * This event loop is known to rely on wall-clock time to schedule future - * timers, because a monotonic time source is not available in PHP by default. + * This event loop is known to rely on wall-clock time to schedule future timers + * when using any version before PHP 7.3, because a monotonic time source is + * only available as of PHP 7.3 (`hrtime()`). * While this does not affect many common use cases, this is an important * distinction for programs that rely on a high time precision or on systems * that are subject to discontinuous time adjustments (time jumps). - * This means that if you schedule a timer to trigger in 30s and then adjust - * your system time forward by 20s, the timer may trigger in 10s. + * This means that if you schedule a timer to trigger in 30s on PHP < 7.3 and + * then adjust your system time forward by 20s, the timer may trigger in 10s. * See also [`addTimer()`](#addtimer) for more details. * * @link http://php.net/manual/en/function.stream-select.php diff --git a/src/Timer/Timers.php b/src/Timer/Timers.php index 1d4ac9b7..a141ff12 100644 --- a/src/Timer/Timers.php +++ b/src/Timer/Timers.php @@ -21,7 +21,12 @@ final class Timers public function updateTime() { - return $this->time = \microtime(true); + // prefer high-resolution timer, available as of PHP 7.3+ + if (\function_exists('hrtime')) { + return $this->time = \hrtime(true) * 1e-9; + } + + return $this->time = \microtime(true) + 1000; } public function getTime() @@ -33,7 +38,7 @@ public function add(TimerInterface $timer) { $id = \spl_object_hash($timer); $this->timers[$id] = $timer; - $this->schedule[$id] = $timer->getInterval() + \microtime(true); + $this->schedule[$id] = $timer->getInterval() + $this->updateTime(); $this->sorted = false; } From 29bf39c1c63153c81e0e34d4a4a7e968aaf4c7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sun, 3 Feb 2019 10:23:43 +0100 Subject: [PATCH 2/2] Improve performance by avoiding platform checks during runtime --- src/Timer/Timers.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Timer/Timers.php b/src/Timer/Timers.php index a141ff12..70adc132 100644 --- a/src/Timer/Timers.php +++ b/src/Timer/Timers.php @@ -18,15 +18,17 @@ final class Timers private $timers = array(); private $schedule = array(); private $sorted = true; + private $useHighResolution; - public function updateTime() + public function __construct() { // prefer high-resolution timer, available as of PHP 7.3+ - if (\function_exists('hrtime')) { - return $this->time = \hrtime(true) * 1e-9; - } + $this->useHighResolution = \function_exists('hrtime'); + } - return $this->time = \microtime(true) + 1000; + public function updateTime() + { + return $this->time = $this->useHighResolution ? \hrtime(true) * 1e-9 : \microtime(true); } public function getTime() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy