ya2 · news · projects · code · about

refactoring of functional tests
[pmachines.git] / lib / engine / profiler.py
CommitLineData
8ee66edd
FC
1from os.path import exists
2
3
4if 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
10class 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
28class 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
62class 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))