135
|
1 """
|
|
2 lsprofcalltree.py - lsprof output which is readable by kcachegrind
|
|
3
|
|
4 Authors:
|
|
5 * David Allouche <david <at> allouche.net>
|
|
6 * Jp Calderone & Itamar Shtull-Trauring
|
|
7 * Johan Dahlin
|
|
8
|
|
9 This software may be used and distributed according to the terms
|
|
10 of the GNU General Public License, incorporated herein by reference.
|
|
11 """
|
|
12
|
|
13 def label(code):
|
|
14 if isinstance(code, str):
|
|
15 return '~' + code # built-in functions ('~' sorts at the end)
|
|
16 else:
|
|
17 return '%s %s:%d' % (code.co_name,
|
|
18 code.co_filename,
|
|
19 code.co_firstlineno)
|
|
20
|
|
21 class KCacheGrind(object):
|
|
22 def __init__(self, profiler):
|
|
23 self.data = profiler.getstats()
|
|
24 self.out_file = None
|
|
25
|
|
26 def output(self, out_file):
|
|
27 self.out_file = out_file
|
|
28 print >> out_file, 'events: Ticks'
|
|
29 self._print_summary()
|
|
30 for entry in self.data:
|
|
31 self._entry(entry)
|
|
32
|
|
33 def _print_summary(self):
|
|
34 max_cost = 0
|
|
35 for entry in self.data:
|
|
36 totaltime = int(entry.totaltime * 1000)
|
|
37 max_cost = max(max_cost, totaltime)
|
|
38 print >> self.out_file, 'summary: %d' % (max_cost,)
|
|
39
|
|
40 def _entry(self, entry):
|
|
41 out_file = self.out_file
|
|
42
|
|
43 code = entry.code
|
|
44 #print >> out_file, 'ob=%s' % (code.co_filename,)
|
|
45 if isinstance(code, str):
|
|
46 print >> out_file, 'fi=~'
|
|
47 else:
|
|
48 print >> out_file, 'fi=%s' % (code.co_filename,)
|
|
49 print >> out_file, 'fn=%s' % (label(code),)
|
|
50
|
|
51 inlinetime = int(entry.inlinetime * 1000)
|
|
52 if isinstance(code, str):
|
|
53 print >> out_file, '0 ', inlinetime
|
|
54 else:
|
|
55 print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime)
|
|
56
|
|
57 # recursive calls are counted in entry.calls
|
|
58 if entry.calls:
|
|
59 calls = entry.calls
|
|
60 else:
|
|
61 calls = []
|
|
62
|
|
63 if isinstance(code, str):
|
|
64 lineno = 0
|
|
65 else:
|
|
66 lineno = code.co_firstlineno
|
|
67
|
|
68 for subentry in calls:
|
|
69 self._subentry(lineno, subentry)
|
|
70 print >> out_file
|
|
71
|
|
72 def _subentry(self, lineno, subentry):
|
|
73 out_file = self.out_file
|
|
74 code = subentry.code
|
|
75 #print >> out_file, 'cob=%s' % (code.co_filename,)
|
|
76 print >> out_file, 'cfn=%s' % (label(code),)
|
|
77 if isinstance(code, str):
|
|
78 print >> out_file, 'cfi=~'
|
|
79 print >> out_file, 'calls=%d 0' % (subentry.callcount,)
|
|
80 else:
|
|
81 print >> out_file, 'cfi=%s' % (code.co_filename,)
|
|
82 print >> out_file, 'calls=%d %d' % (
|
|
83 subentry.callcount, code.co_firstlineno)
|
|
84
|
|
85 totaltime = int(subentry.totaltime * 1000)
|
|
86 print >> out_file, '%d %d' % (lineno, totaltime)
|