Commit | Line | Data |
---|---|---|
8ee66edd FC |
1 | from os.path import exists |
2 | ||
3 | ||
4 | if not exists('main.pyo'): # we don't deploy cProfile | |
5 | from cProfile import Profile | |
6 | from pstats import Stats | |
7 | from io import StringIO | |
8 | ||
9 | ||
10 | class AbsProfiler: | |
11 | ||
12 | @staticmethod | |
13 | def build(percall): | |
14 | prof_cls = AbsProfiler | |
15 | if not exists('main.pyo'): | |
16 | prof_cls = PerCallProfiler if percall else Profiler | |
17 | return prof_cls(percall) | |
18 | ||
19 | def __init__(self, percall): pass | |
20 | ||
21 | def printstats(self): pass | |
22 | ||
23 | def toggle(self): pass | |
24 | ||
25 | def destroy(self): pass | |
26 | ||
27 | ||
28 | class Profiler(AbsProfiler): | |
29 | ||
30 | def __init__(self, percall): | |
31 | AbsProfiler.__init__(self, percall) | |
32 | self.percall = percall | |
33 | self.is_profiling = False # we can't infer from cProfile | |
34 | self.prof = Profile() | |
35 | self.stats = None | |
36 | ||
37 | def toggle(self): | |
38 | if not self.is_profiling: self.__enable() | |
39 | else: | |
40 | self.__disable() | |
41 | self.printstats() | |
42 | ||
43 | def __enable(self): | |
44 | self.prof.enable() | |
45 | self.is_profiling = True | |
46 | ||
47 | def __disable(self): | |
48 | self.prof.disable() | |
49 | self.is_profiling = False | |
50 | ||
51 | def printstats(self): | |
52 | self.prof.disable() | |
53 | sio = StringIO() | |
54 | self.stats = Stats(self.prof, stream=sio).sort_stats('cumulative') | |
55 | self.stats.print_stats() | |
56 | self._print_lines(sio) | |
57 | ||
58 | @staticmethod | |
59 | def _print_lines(sio): print(sio.getvalue()) | |
60 | ||
61 | ||
62 | class PerCallProfiler(Profiler): | |
63 | ||
64 | def _print_lines(self, sio): | |
65 | lines = sio.getvalue().split('\n') | |
66 | header_lines = lines[:5] | |
67 | content_lines = [line.split() for line in lines[5:] if line] | |
68 | sorted_lines = sorted(content_lines, key=lambda line: line[4]) | |
69 | sorted_lines = reversed(sorted_lines) | |
70 | # line[4] is the percall value | |
71 | joined_lines = ['\t'.join(line) for line in sorted_lines] | |
72 | print('\n'.join(header_lines + joined_lines)) |