Coverage for larch/utils/debugtimer.py: 19%
57 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
1#!/usr/bin/env python
3import time
4import sys
5from tabulate import tabulate
7class DebugTimer():
8 '''
9 Measure run times for lines of code and summarize results
10 '''
11 def __init__(self, initial_message=None, verbose=False,
12 with_mod_count=False, precision=3):
13 self.verbose = verbose
14 self.precision = precision
15 self.with_mod_count = with_mod_count
16 self.clear(initial_message=initial_message)
18 def clear(self, initial_message=None):
19 self.data = []
20 if initial_message is None:
21 initial_message = 'DebugTimer'
22 self.add(f'initial_message {time.ctime()}')
24 def add(self, msg=None):
25 if msg is None:
26 msg = time.ctime()
27 self.data.append((msg, len(sys.modules), time.perf_counter()))
28 if self.verbose:
29 print(msg)
31 def get_table(self, precision=None, with_mod_count=True,
32 tablefmt='simple_outline'):
33 prec = self.precision
34 if precision is not None:
35 prec = precision
36 with_nmod= self.with_mod_count
37 if with_mod_count is not None:
38 with_nmod = with_mod_count
39 m0, n0, t0 = self.data[0]
40 tprev= t0
41 header = ['Message','Delta Time', 'Total Time']
42 row = [m0, 0, 0]
43 if with_nmod:
44 header.append('# Modules')
45 row.append(n0)
46 table = [row[:]]
47 for m, n, t in self.data[1:]:
48 tt, dt = t-t0, t-tprev
49 row = [m, dt, tt, n] if with_nmod else [m, dt, tt]
50 table.append(row[:])
51 tprev = t
52 ffmt = f'.{prec}f'
53 return tabulate(table, header, floatfmt=ffmt, tablefmt=tablefmt)
55 def show(self, precision=None, with_mod_count=True,
56 tablefmt='outline'):
57 print(self.get_table(precision=precision,
58 with_mod_count=with_mod_count,
59 tablefmt=tablefmt))
62def debugtimer(initial_message=None, with_mod_count=False,
63 verbose=False, precision=3):
64 '''debugtimer returns a DebugTimer object to measure the runtime of
65 portions of code, and then write a simple report of the results.
67 Arguments
68 ------------
69 iniitial message: str, optional initial message ['DebugTimer']
70 precision: int, precision for timing results [3]
71 with_mod_count: bool, whether to include number of imported modules [True]
72 verbose: bool, whether to print() each message when entered [False]
74 Returns
75 --------
76 DebugTimer object, with methods:
78 clear(initial_message=None) -- reset Timer
79 add(message) -- record time, with message
80 show(tablefmt='simple_outline') -- print timer report
81 where tableftmt can be any tablefmt for the tabulate module.
83 Example:
84 -------
85 timer = debugtimer('started timer', precision=4)
86 result = foo(x=100)
87 timer.add('ran foo')
88 bar(result)
89 timer.add('ran bar')
90 timer.show(tablefmt='outline')
91 '''
92 return DebugTimer(initial_message=initial_message,
93 with_mod_count=with_mod_count,
94 verbose=verbose, precision=precision)
97if __name__ == '__main__':
98 dt = debugtimer('test timer')
99 time.sleep(1.102)
100 dt.add('slept for 1.102 seconds')
101 import numpy as np
102 n = 10_000_000
103 x = np.arange(n, dtype='float64')/3.0
104 dt.add(f'created numpy array len={n}')
105 s = np.sqrt(x)
106 dt.add('took sqrt')
107 dt.show(tablefmt='outline')