Coverage for utility/profiling.py : 30%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import collections
2import timeit
4class Profiler:
5 """
6 Profiler
7 This class provides a simple profiling mechanism for measuring the execution time of different sections of code. It records the time taken for each named section of code and calculates the mean and variance of the recorded times.
9 Methods:
10 __init__(): Initialize the Profiler object with default settings.
11 reset(): Reset the profiler data and start tracking time from the current point.
12 time(name): Record the execution time for a specific section of code with the given name.
13 means(): Get the dictionary of mean times for each recorded section.
14 vars(): Get the dictionary of variances of the recorded times for each section.
15 stds(): Get the dictionary of standard deviations of the recorded times for each section.
16 total(): Calculate the total time taken for all recorded sections.
17 summary(prefix=""): Generate a summary of the profiling data with mean time, standard deviation, and percentage of total time for each recorded section.
19 Usage:
20 The Profiler object can be used to measure the execution time of different parts of a code by calling the `time` method with a descriptive name for each section. After profiling, the `summary` method can be used to print a summary of the profiling data.
22 Example:
23 profiler = Profiler()
24 for i in range(10):
25 # Code segment to be profiled
26 profiler.time("Code Segment %d" % i)
28 print(profiler.summary("Profiling Results:"))
29 """
31 def __init__(self):
32 self._means = collections.defaultdict(int)
33 self._vars = collections.defaultdict(int)
34 self._counts = collections.defaultdict(int)
35 self.reset()
37 def reset(self):
38 self.last_time = timeit.default_timer()
40 def time(self, name):
41 now = timeit.default_timer()
42 x = now - self.last_time
43 self.last_time = now
45 n = self._counts[name]
47 mean = self._means[name] + (x - self._means[name]) / (n + 1)
48 var = (n * self._vars[name] + n * (self._means[name] - mean) ** 2 + (x - mean) ** 2) / (n + 1)
50 self._means[name] = mean
51 self._vars[name] = var
52 self._counts[name] += 1
54 def means(self):
55 return self._means
57 def vars(self):
58 return self._vars
60 def stds(self):
61 return {k: v ** 0.5 for k, v in self._vars.items()}
63 def total(self):
64 return sum(self.means().values())
66 def summary(self, prefix=""):
67 means = self.means()
68 stds = self.stds()
69 total = sum(means.values())
71 result = prefix
72 for k in sorted(means, key=means.get, reverse=True):
73 result += f"\n -> %s: %.3fms +- %.3fms (%.2f%%) " % (
74 k,
75 1000 * means[k],
76 1000 * stds[k],
77 100 * means[k] / total,
78 )
79 result += "\nTotal: %.3fms" % (1000 * total)
80 return result