forked from samuelcolvin/python-devtools
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimer.py
More file actions
92 lines (73 loc) · 2.46 KB
/
Copy pathtimer.py
File metadata and controls
92 lines (73 loc) · 2.46 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
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 f'{self._name}: {self.elapsed():0.{dp}f}s elapsed'
else:
return f'{self.elapsed():0.{dp}f}s elapsed'
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(f' {r.str(self.dp)}', file=self.file)
times.add(r.elapsed())
if times:
from statistics import mean, stdev
print(
f'{len(times)} times: '
f'mean={mean(times):0.{self.dp}f}s '
f'stdev={stdev(times) if len(times) > 1 else 0:0.{self.dp}f}s '
f'min={min(times):0.{self.dp}f}s '
f'max={max(times):0.{self.dp}f}s',
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()