# timing.py
"""Simple task timing utility."""
import datetime
import time
import numpy as np
[docs]
class Timer(object):
"""Simple timer.
Example usage:
.. code::
# set up timer
import csky as cy
timer = cy.time.Timer()
time = timer.time
# time some things
with time('some lengthy calculation'):
[do some work here]
with time('another lengthy calculation'):
[do some more work here]
# get summary
print(timer)
"""
class Task(object):
fts = datetime.datetime.fromtimestamp
def __enter__(self):
self._start = time.time()
def __exit__(self, type, value, traceback):
self._stop = time.time()
print('\n{} elapsed.'.format(self.timedelta))
def __repr__(self):
return 'Task({})'.format(self.timedelta)
@property
def start_timestamp(self):
return self._start
@property
def stop_timestamp(self):
return self._stop
@property
def start(self):
return self.fts(self._start)
@property
def stop(self):
return self.fts(self._stop)
@property
def timedelta(self):
return self.fts(self._stop) - self.fts(self._start)
@property
def elapsed(self):
return self._stop - self._start
[docs]
def __init__(self):
self.tasks = {}
self.tasklist = []
self.tasknames = []
def time(self, name=''):
task = self.Task()
if not name:
name = '{}'.format(len(self.tasklist))
if name in self.tasknames:
i = self.tasknames.index(name)
self.tasknames.pop(i)
self.tasklist.pop(i)
self.tasklist.append(task)
self.tasknames.append(name)
self.tasks[name] = task
return task
def _make_str(self, values, prec=None, total=None):
out = []
totstr = 'total measured time'
length = max(map(len, self.tasknames))
if total:
length = max(length, len(totstr))
fmt = '{{:{}}}'.format(length)
if prec is None:
fmt += ' | {}'
else:
fmt += ' | {{:.{}f}}'.format(prec)
for (name, value) in zip(self.tasknames, values):
out.append(fmt.format(name, value))
if total:
tot = np.sum(values)
out.append(len(out[-1]) * '-')
out.append(fmt.format('total', tot))
return '\n'.join(out)
def __str__(self):
timedeltas = [task.timedelta for task in self.tasklist]
return self._make_str(timedeltas, total=True)
def ratios(self, name):
i = np.where(np.array(self.tasknames) == name)[0]
if len(i) == 1:
i = i[0]
else:
raise ValueError('could not find unique match for task "{}"'.format(i))
durations = np.array([task.elapsed for task in self.tasklist])
return self._make_str(durations / durations[i], prec=4)