lsprofcalltree.py
90 lines
| 2.7 KiB
| text/x-python
|
PythonLexer
/ mercurial / lsprofcalltree.py
Nicolas Dumazet
|
r8024 | """ | ||
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) | ||||