-
-
Notifications
You must be signed in to change notification settings - Fork 50
Expand file tree
/
Copy pathtimer.py
More file actions
95 lines (76 loc) · 2.53 KB
/
Copy pathtimer.py
File metadata and controls
95 lines (76 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
from time import time
__all__ = ('Timer',)
class TimerResult:
def __init__(self, name=None, verbose=True):
self._name = name
self.verbose = verbose
self.finish = None
self.start = time()
def capture(self):
self.finish = time()
def elapsed(self):
if self.finish:
return self.finish - self.start
else:
return -1
def str(self, dp=3):
if self._name:
return '{}: {:0.{dp}f}s elapsed'.format(self._name, self.elapsed(), dp=dp)
else:
return '{:0.{dp}f}s elapsed'.format(self.elapsed(), dp=dp)
def __str__(self):
return self.str()
_SUMMARY_TEMPLATE = '{count} times: mean={mean:0.{dp}f}s stdev={stddev:0.{dp}f}s min={min:0.{dp}f}s max={max:0.{dp}f}s'
class Timer:
def __init__(self, name=None, verbose=True, file=None, dp=3):
self.file = file
self.dp = dp
self._name = name
self._verbose = verbose
self.results = []
def __call__(self, name=None, verbose=None):
if name:
self._name = name
if verbose is not None:
self._verbose = verbose
return self
def start(self, name=None, verbose=None):
self.results.append(TimerResult(name or self._name, self._verbose if verbose is None else verbose))
return self
def capture(self, verbose=None):
r = self.results[-1]
r.capture()
print_ = r.verbose if verbose is None else verbose
if print_:
print(r.str(self.dp), file=self.file, flush=True)
return r
def summary(self, verbose=False):
times = set()
for r in self.results:
if not r.finish:
r.capture()
if verbose:
print(' {}'.format(r.str(self.dp)), file=self.file)
times.add(r.elapsed())
if times:
from statistics import mean, stdev
print(
_SUMMARY_TEMPLATE.format(
count=len(times),
mean=mean(times),
stddev=stdev(times) if len(times) > 1 else 0,
min=min(times),
max=max(times),
dp=self.dp,
),
file=self.file,
flush=True,
)
else:
raise RuntimeError('timer not started')
return times
def __enter__(self):
self.start()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.capture()