From 326413a2715e58432a96d63e3eb1025fa2226348 Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Fri, 16 Nov 2018 16:48:36 +0400 Subject: [PATCH 1/2] Use time.monotonic if available --- progress/__init__.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/progress/__init__.py b/progress/__init__.py index 122406f..ebd7908 100644 --- a/progress/__init__.py +++ b/progress/__init__.py @@ -18,7 +18,10 @@ from collections import deque from datetime import timedelta from math import ceil from sys import stderr -from time import time +try: + from time import monotonic +except ImportError: + from time import time as monotonic __version__ = '1.4' @@ -35,7 +38,7 @@ class Infinite(object): def __init__(self, message='', **kwargs): self.index = 0 - self.start_ts = time() + self.start_ts = monotonic() self.avg = 0 self._ts = self.start_ts self._xput = deque(maxlen=self.sma_window) @@ -58,7 +61,7 @@ class Infinite(object): @property def elapsed(self): - return int(time() - self.start_ts) + return int(monotonic() - self.start_ts) @property def elapsed_td(self): @@ -102,7 +105,7 @@ class Infinite(object): return self.file.isatty() if self.check_tty else True def next(self, n=1): - now = time() + now = monotonic() dt = now - self._ts self.update_avg(n, dt) self._ts = now From c1e07104e1debb90be7c58168d601c3e820b77b7 Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Fri, 16 Nov 2018 16:52:10 +0400 Subject: [PATCH 2/2] Update avg/eta/eta_td less frequently When the progress bar is updated frequently (every few milliseconds), the eta can change so quickly that it's impossible to read. This commit updates the average while sma_window is being filled, then after every second. This means we're calling monotonic/time often, but those calls take less than 100 nsec per loop on Linux, Windows and macOS [0], which is equivalent to one attribute lookup or two. [0]: https://github.com/python-trio/trio/issues/33 --- progress/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/progress/__init__.py b/progress/__init__.py index ebd7908..ca7f6b4 100644 --- a/progress/__init__.py +++ b/progress/__init__.py @@ -40,6 +40,7 @@ class Infinite(object): self.index = 0 self.start_ts = monotonic() self.avg = 0 + self._avg_update_ts = self.start_ts self._ts = self.start_ts self._xput = deque(maxlen=self.sma_window) for key, val in kwargs.items(): @@ -69,8 +70,14 @@ class Infinite(object): def update_avg(self, n, dt): if n > 0: + xput_len = len(self._xput) self._xput.append(dt / n) - self.avg = sum(self._xput) / len(self._xput) + now = monotonic() + # update when we're still filling _xput, then after every second + if (xput_len < self.sma_window or + now - self._avg_update_ts > 1): + self.avg = sum(self._xput) / len(self._xput) + self._avg_update_ts = now def update(self): pass