Skip to content
Snippets Groups Projects
Commit 34b915ac authored by David Hammer's avatar David Hammer
Browse files

Improving, simplifying timers

parent 8b3128b5
No related branches found
No related tags found
2 merge requests!12Snapshot: field test deployed version as of end of run 202201,!3Base correction device, CalCat interaction, DSSC and AGIPD devices
......@@ -3,7 +3,7 @@ import functools
import inspect
import threading
import time
import timeit
from timeit import default_timer
import numpy as np
......@@ -164,11 +164,9 @@ class RepeatingTimer:
self,
interval,
callback,
timer=timeit.default_timer,
start_now=True,
daemon=True,
):
self.timer = timer
self.stopped = True
self.interval = interval
self.callback = callback
......@@ -178,19 +176,19 @@ class RepeatingTimer:
def start(self):
self.stopped = False
self.wakeup_time = self.timer() + self.interval
self.wakeup_time = default_timer() + self.interval
def runner():
while not self.stopped:
now = self.timer()
now = default_timer()
while now < self.wakeup_time:
diff = self.wakeup_time - now
time.sleep(diff)
if self.stopped:
return
now = self.timer()
now = default_timer()
self.callback()
self.wakeup_time = self.timer() + self.interval
self.wakeup_time = default_timer() + self.interval
self.thread = threading.Thread(target=runner, daemon=self.daemonize)
self.thread.start()
......@@ -217,26 +215,72 @@ class ExponentialMovingAverage:
class WindowRateTracker:
def __init__(self, buffer_size=20, time_window=20, timer=timeit.default_timer):
def __init__(self, buffer_size=20, time_window=10):
self.time_window = time_window
self.buffer_size = buffer_size
self.deque = collections.deque(maxlen=self.buffer_size)
self.timer = timer
def update(self):
now = self.timer()
self.deque.append(now)
self.deque.append(default_timer())
def get(self):
now = self.timer()
now = default_timer()
cutoff = now - self.time_window
try:
while self.deque[0] < cutoff:
self.deque.popleft()
except IndexError:
return 0
if len(self.deque) < 2:
return 0
if len(self.deque) < self.buffer_size:
# TODO: estimator avoiding ramp-up of when starting anew
return len(self.deque) / self.time_window
else:
# if going faster than buffer size per time window, look at timestamps
return len(self.deque) / (self.deque[-1] - self.deque[0])
oldest, newest = self.deque[0], self.deque[-1]
buffer_span = newest - oldest
period = buffer_span / (self.buffer_size - 1)
if (now - newest) < period:
# no new estimate yet, expecting new event after period
return 1 / period
else:
return self.buffer_size / (now - oldest)
class Stopwatch:
"""Context manager measuring time spent in context.
Keyword arguments:
name: if not None, will appear in string representation
also, if not None, will automatically print self when done
"""
def __init__(self, name=None):
self.stop_time = None
self.name = name
def __enter__(self):
self.start_time = default_timer()
return self
def __exit__(self, t, v, tb): # type, value and traceback irrelevant
self.stop_time = default_timer()
if self.name is not None:
print(repr(self))
@property
def elapsed(self):
if self.stop_time is not None:
return self.stop_time - self.start_time
else:
return default_timer() - self.start_time
def __str__(self):
return self.__repr__()
def __repr__(self):
if self.name is None:
return f"{self.elapsed():.3f} s"
else:
return f"{self.name}: {self.elapsed():.3f} s"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment