[PATCH 1 of 1] Adding support for kcachegrind, using lsprofcalltree
Nicolas Dumazet
nicdumz at gmail.com
Mon Mar 23 12:36:28 CDT 2009
# HG changeset patch
# User Nicolas Dumazet <nicdumz.commits at gmail.com>
# Date 1237829437 -32400
# Node ID a4e5223240a610818c2a0fae70e53d69e0292504
# Parent c63c30ae9e39229ff3cbb2f452ef11a009a363f2
Adding support for kcachegrind, using lsprofcalltree
diff -r c63c30ae9e39 -r a4e5223240a6 mercurial/commands.py
--- a/mercurial/commands.py Mon Mar 23 15:32:29 2009 +0100
+++ b/mercurial/commands.py Tue Mar 24 02:30:37 2009 +0900
@@ -2974,6 +2974,8 @@
('', 'debugger', None, _('start debugger')),
('', 'encoding', util._encoding, _('set the charset encoding')),
('', 'encodingmode', util._encodingmode, _('set the charset encoding mode')),
+ ('', 'kcachegrind', '',
+ _('output kcachegrind execution profile to specified file')),
('', 'lsprof', None, _('print improved command execution profile')),
('', 'traceback', None, _('print traceback on exception')),
('', 'time', None, _('time how long the command takes')),
diff -r c63c30ae9e39 -r a4e5223240a6 mercurial/dispatch.py
--- a/mercurial/dispatch.py Mon Mar 23 15:32:29 2009 +0100
+++ b/mercurial/dispatch.py Tue Mar 24 02:30:37 2009 +0900
@@ -397,7 +397,7 @@
stats.strip_dirs()
stats.sort_stats('time', 'calls')
stats.print_stats(40)
- elif options['lsprof']:
+ elif options['kcachegrind'] or options['lsprof']:
try:
from mercurial import lsprof
except ImportError:
@@ -410,8 +410,21 @@
return checkargs()
finally:
p.disable()
- stats = lsprof.Stats(p.getstats())
- stats.sort()
- stats.pprint(top=10, file=sys.stderr, climit=5)
+ if options['kcachegrind']:
+ import lsprofcalltree
+ calltree = lsprofcalltree.KCacheGrind(p)
+
+ path = options['kcachegrind']
+ path = os.path.expanduser(path)
+ path = ui.expandpath(path)
+
+ f = open(path, 'w+')
+ calltree.output(f)
+ f.close()
+ else:
+ # lsprof handling
+ stats = lsprof.Stats(p.getstats())
+ stats.sort()
+ stats.pprint(top=10, file=sys.stderr, climit=5)
else:
return checkargs()
diff -r c63c30ae9e39 -r a4e5223240a6 mercurial/lsprofcalltree.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/lsprofcalltree.py Tue Mar 24 02:30:37 2009 +0900
@@ -0,0 +1,90 @@
+"""
+lsprofcalltree.py - lsprof output which is readable by kcachegrind
+
+Authors:
+ * David Allouche <david at allouche.net>
+ * Jp Calderone & Itamar Shtull-Trauring
+ * Johan Dahlin
+
+This software may be used and distributed according to the terms
+of the GNU General Public License, incorporated herein by reference.
+"""
+
+import optparse
+import os
+import sys
+
+def label(code):
+ if isinstance(code, str):
+ return '~' + code # built-in functions ('~' sorts at the end)
+ else:
+ return '%s %s:%d' % (code.co_name,
+ code.co_filename,
+ code.co_firstlineno)
+
+class KCacheGrind(object):
+ def __init__(self, profiler):
+ self.data = profiler.getstats()
+ self.out_file = None
+
+ def output(self, out_file):
+ self.out_file = out_file
+ print >> out_file, 'events: Ticks'
+ self._print_summary()
+ for entry in self.data:
+ self._entry(entry)
+
+ def _print_summary(self):
+ max_cost = 0
+ for entry in self.data:
+ totaltime = int(entry.totaltime * 1000)
+ max_cost = max(max_cost, totaltime)
+ print >> self.out_file, 'summary: %d' % (max_cost,)
+
+ def _entry(self, entry):
+ out_file = self.out_file
+
+ code = entry.code
+ #print >> out_file, 'ob=%s' % (code.co_filename,)
+ if isinstance(code, str):
+ print >> out_file, 'fi=~'
+ else:
+ print >> out_file, 'fi=%s' % (code.co_filename,)
+ print >> out_file, 'fn=%s' % (label(code),)
+
+ inlinetime = int(entry.inlinetime * 1000)
+ if isinstance(code, str):
+ print >> out_file, '0 ', inlinetime
+ else:
+ print >> out_file, '%d %d' % (code.co_firstlineno, inlinetime)
+
+ # recursive calls are counted in entry.calls
+ if entry.calls:
+ calls = entry.calls
+ else:
+ calls = []
+
+ if isinstance(code, str):
+ lineno = 0
+ else:
+ lineno = code.co_firstlineno
+
+ for subentry in calls:
+ self._subentry(lineno, subentry)
+ print >> out_file
+
+ def _subentry(self, lineno, subentry):
+ out_file = self.out_file
+ code = subentry.code
+ #print >> out_file, 'cob=%s' % (code.co_filename,)
+ print >> out_file, 'cfn=%s' % (label(code),)
+ if isinstance(code, str):
+ print >> out_file, 'cfi=~'
+ print >> out_file, 'calls=%d 0' % (subentry.callcount,)
+ else:
+ print >> out_file, 'cfi=%s' % (code.co_filename,)
+ print >> out_file, 'calls=%d %d' % (
+ subentry.callcount, code.co_firstlineno)
+
+ totaltime = int(subentry.totaltime * 1000)
+ print >> out_file, '%d %d' % (lineno, totaltime)
diff -r c63c30ae9e39 -r a4e5223240a6 tests/test-debugcomplete.out
--- a/tests/test-debugcomplete.out Mon Mar 23 15:32:29 2009 +0100
+++ b/tests/test-debugcomplete.out Tue Mar 24 02:30:37 2009 +0900
@@ -97,6 +97,7 @@
--encoding
--encodingmode
--help
+--kcachegrind
--lsprof
--noninteractive
--profile
@@ -127,6 +128,7 @@
--errorlog
--help
--ipv6
+--kcachegrind
--lsprof
--name
--noninteractive
diff -r c63c30ae9e39 -r a4e5223240a6 tests/test-extension.out
--- a/tests/test-extension.out Mon Mar 23 15:32:29 2009 +0100
+++ b/tests/test-extension.out Tue Mar 24 02:30:37 2009 +0900
@@ -48,6 +48,7 @@
--debugger start debugger
--encoding set the charset encoding (default: ascii)
--encodingmode set the charset encoding mode (default: strict)
+ --kcachegrind output kcachegrind execution profile to specified file
--lsprof print improved command execution profile
--traceback print traceback on exception
--time time how long the command takes
More information about the Mercurial-devel
mailing list