Source code for tdg.performance.timer

import time

[docs]class Timer: r''' A simple timer which provides a context manager for use with ``with`` statements. Parameters ---------- log: A logger's convenience function, such as ``.debug`` or ``.info``. Where to log the timer. message: str The message on entry and exit from the timer's context, unless stop_message is also provided, in which case this is only on entry. stop_message: str An optionally different message to print on completion. time: a function which returns times that can be subtracted to get an interval. Examples include ``time.perf_counter`` or ``time.process_time`` as `in the standard library <https://docs.python.org/3/library/time.html#time.perf_counter>`_. per: int How many to divide by to determine the marginal cost. For example, >>> with Timer(logger.debug, 'Task', per=10): >>> time.sleep(0.3, time=time.process_time) 2023-04-27 22:39:18,076 root DEBUG Task ... 2023-04-27 22:39:18,383 root DEBUG ... Task [0.001954 seconds] (0.000195 seconds each) >>> with Timer(logger.debug, 'Begin', 'End', time=time.process_time): >>> time.sleep(0.3) 2023-04-27 22:39:51,286 root DEBUG Begin ... 2023-04-27 22:39:51,604 root DEBUG ... End [0.001070 seconds] >>> with tdg.performance.Timer(logger.debug, 'With perf_counter', time=time.perf_counter): >>> time.sleep(0.3) 2023-04-27 22:45:55,955 root DEBUG With perf_counter ... 2023-04-27 22:45:56,258 root DEBUG ... With perf_counter [0.300386 seconds] ''' def __init__(self, log, message, stop_message=None, time=time.perf_counter, per=1 ): self.time = time self.fmt = '8f' self.log = log self.per = per if stop_message: self.start_msg = message self.stop_msg = stop_message else: self.start_msg = message self.stop_msg = message self.strt_time = None self.stop_time = None
[docs] def start(self): r'''Start the timer.''' self.strt_time = self.time()
[docs] def stop(self): r'''Stop the timer.''' self.stop_time = self.time()
[docs] def elapsed(self): r''' The difference between the stop and start time. If the timer was never :func:`~.Timer.start`\ ed, 0; if the timer was never :func:`~.Timer.stop`\ ped, stop now and and subtract. ''' if self.strt_time is None: return 0. if self.stop_time is None: self.stop() return self.stop_time - self.strt_time
def __enter__(self): self.log(f'{self.start_msg} ...') self.start() def __exit__(self, exc_type, exc_value, traceback): self.stop() diff = self.elapsed() self.log(f'... {self.stop_msg} [{diff:{self.fmt}} seconds]' + (f' ({diff/self.per:{self.fmt}} seconds each * {self.per})' if self.per > 1 else ''))