-
Notifications
You must be signed in to change notification settings - Fork 7
/
timer_cm.py
52 lines (51 loc) · 1.62 KB
/
timer_cm.py
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
from decimal import Decimal
from math import ceil, log10
from timeit import default_timer
class Timer(object):
def __init__(self, name, print_results=True):
self.elapsed = Decimal()
self._name = name
self._print_results = print_results
self._start_time = None
self._children = {}
self._count = 0
def __enter__(self):
self.start()
return self
def __exit__(self, *_):
self.stop()
if self._print_results:
self.print_results()
def child(self, name):
try:
return self._children[name]
except KeyError:
result = Timer(name, print_results=False)
self._children[name] = result
return result
def start(self):
self._count += 1
self._start_time = self._get_time()
def stop(self):
self.elapsed += self._get_time() - self._start_time
def print_results(self):
print(self._format_results())
def _format_results(self, indent=' '):
children = self._children.values()
elapsed = self.elapsed or sum(c.elapsed for c in children)
result = '%s: %.3fs' % (self._name, elapsed)
max_count = max(c._count for c in children) if children else 0
count_digits = 0 if max_count <= 1 else int(ceil(log10(max_count + 1)))
for child in sorted(children, key=lambda c: c.elapsed, reverse=True):
lines = child._format_results(indent).split('\n')
child_percent = child.elapsed / elapsed * 100
lines[0] += ' (%d%%)' % child_percent
if count_digits:
# `+2` for the 'x' and the space ' ' after it:
lines[0] = ('%dx ' % child._count).rjust(count_digits + 2) \
+ lines[0]
for line in lines:
result += '\n' + indent + line
return result
def _get_time(self):
return Decimal(default_timer())