Mercurial > public > mercurial-scm > hg
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) |