-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathtimer.py
65 lines (44 loc) · 1.71 KB
/
timer.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
53
54
55
56
57
58
59
60
61
62
63
64
65
__all__ = ['timer_start', 'timer_lap', 'timer_stop', 'timer_stop_all']
import atexit
import sys
import time
from .io_helpers import log
def seconds_to_most_relevant_unit(s: float) -> str:
s *= 1e6
if s < 1000:
return f'{s:.3f}µs'
s /= 1000
if s < 1000:
return f'{s:.3f}ms'
s /= 1000
if s < 60:
return f'{s:.3f}s'
s /= 60
return f'{int(s):d}m {(s / 60) % 60:.3f}s'
def timer_start(name: str=sys.argv[0]):
now_wall, now_cpu = time.perf_counter(), time.process_time()
timers[name] = (now_wall, now_cpu, now_wall, now_cpu, 1)
def timer_lap(name: str=sys.argv[0]):
now_wall, now_cpu = time.perf_counter(), time.process_time()
*x, prev_wall, prev_cpu, lap = timers[name]
dt_wall = seconds_to_most_relevant_unit(now_wall - prev_wall)
dt_cpu = seconds_to_most_relevant_unit(now_cpu - prev_cpu )
log(f'Timer {name} lap #{lap}: {dt_wall} wall, {dt_cpu} CPU\n')
timers[name] = (*x, time.perf_counter(), time.process_time(), lap + 1)
def timer_stop(name: str=sys.argv[0]):
now_wall, now_cpu = time.perf_counter(), time.process_time()
prev_wall, prev_cpu, *_ = timers.pop(name)
dt_wall = seconds_to_most_relevant_unit(now_wall - prev_wall)
dt_cpu = seconds_to_most_relevant_unit(now_cpu - prev_cpu )
log(f'Timer {name}: {dt_wall} wall, {dt_cpu} CPU\n')
def timer_stop_all():
now_wall, now_cpu = time.perf_counter(), time.process_time()
while timers:
k, v = timers.popitem()
prev_wall, prev_cpu, *_ = v
dt_wall = seconds_to_most_relevant_unit(now_wall - prev_wall)
dt_cpu = seconds_to_most_relevant_unit(now_cpu - prev_cpu )
log(f'Timer {k}: {dt_wall} wall, {dt_cpu} CPU\n')
################################################################################
timers = {}
atexit.register(timer_stop_all)