comparison mercurial/lsprofcalltree.py @ 8024:9a1b86cfd29e

profiling: Adding support for kcachegrind output format, using lsprofcalltree
author Nicolas Dumazet <nicdumz.commits@gmail.com>
date Wed, 08 Apr 2009 14:20:57 +0200
parents
children beae42f3d93b
comparison
equal deleted inserted replaced
8023:fd9debb3ea1b 8024:9a1b86cfd29e
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 import optparse
14 import os
15 import sys
16
17 def label(code):
18 if isinstance(code, str):
19 return '~' + code # built-in functions ('~' sorts at the end)
20 else:
21 return '%s %s:%d' % (code.co_name,
22 code.co_filename,
23 code.co_firstlineno)
24
25 class KCacheGrind(object):
26 def __init__(self, profiler):
27 self.data = profiler.getstats()
28 self.out_file = None
29
30 def output(self, out_file):
31 self.out_file = out_file
32 print >> out_file, 'events: Ticks'
33 self._print_summary()
34 for entry in self.data:
35 self._entry(entry)
36
37 def _print_summary(self):
38 max_cost = 0
39 for entry in self.data:
40 totaltime = int(entry.totaltime * 1000)
41 max_cost = max(max_cost, totaltime)
42 print >> self.out_file, 'summary: %d' % (max_cost,)
43
44 def _entry(self, entry):
45 out_file = self.out_file
46
47 code = entry.code
48 #print >> out_file, 'ob=%s' % (code.co_filename,)
49 if isinstance(code, str):
50 print >> out_file, 'fi=~'
51 else:
52 print >> out_file, 'fi=%s' % (code.co_filename,)
53 print >> out_file, 'fn=%s' % (label(code),)
54
55 inlinetime = int(entry.inlinetime * 1000)
56 if isinstance(code, str):
57 print >> out_file, '0 ', inlinetime
58 else:
59 print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime)
60
61 # recursive calls are counted in entry.calls
62 if entry.calls:
63 calls = entry.calls
64 else:
65 calls = []
66
67 if isinstance(code, str):
68 lineno = 0
69 else:
70 lineno = code.co_firstlineno
71
72 for subentry in calls:
73 self._subentry(lineno, subentry)
74 print >> out_file
75
76 def _subentry(self, lineno, subentry):
77 out_file = self.out_file
78 code = subentry.code
79 #print >> out_file, 'cob=%s' % (code.co_filename,)
80 print >> out_file, 'cfn=%s' % (label(code),)
81 if isinstance(code, str):
82 print >> out_file, 'cfi=~'
83 print >> out_file, 'calls=%d 0' % (subentry.callcount,)
84 else:
85 print >> out_file, 'cfi=%s' % (code.co_filename,)
86 print >> out_file, 'calls=%d %d' % (
87 subentry.callcount, code.co_firstlineno)
88
89 totaltime = int(subentry.totaltime * 1000)
90 print >> out_file, '%d %d' % (lineno, totaltime)