diff options
author | jlew <jlew.blackout@gmail.com> | 2010-06-09 20:28:29 (GMT) |
---|---|---|
committer | jlew <jlew.blackout@gmail.com> | 2010-06-09 20:28:29 (GMT) |
commit | e8111b3971aeb842a127d382080e8b0f9ccf58c7 (patch) | |
tree | 94edfcf43d854f4aa2f0af1cdc019228321e200c /devtools/profilers | |
parent | afbfec71f431786f04f44e1c650281b0baac0e00 (diff) |
Uploaded a profiler I have been playing with. (Ticket #11)
Diffstat (limited to 'devtools/profilers')
-rw-r--r-- | devtools/profilers/kcachegrind/lsprofcalltree.py | 119 | ||||
-rw-r--r-- | devtools/profilers/kcachegrind/usage.txt | 4 |
2 files changed, 123 insertions, 0 deletions
diff --git a/devtools/profilers/kcachegrind/lsprofcalltree.py b/devtools/profilers/kcachegrind/lsprofcalltree.py new file mode 100644 index 0000000..efedc5a --- /dev/null +++ b/devtools/profilers/kcachegrind/lsprofcalltree.py @@ -0,0 +1,119 @@ +# lsprofcalltree.py: lsprof output which is readable by kcachegrind +# David Allouche +# Jp Calderone & Itamar Shtull-Trauring +# Johan Dahlin + +import optparse +import os +import sys + +try: + import cProfile +except ImportError: + raise SystemExit("This script requires cProfile from Python 2.5") + +def label(code): + if isinstance(code, str): + return ('~', 0, 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) + +def main(args): + usage = "%s [-o output_file_path] scriptfile [arg] ..." + parser = optparse.OptionParser(usage=usage % sys.argv[0]) + parser.allow_interspersed_args = False + parser.add_option('-o', '--outfile', dest="outfile", + help="Save stats to <outfile>", default=None) + + if not sys.argv[1:]: + parser.print_usage() + sys.exit(2) + + options, args = parser.parse_args() + + if not options.outfile: + options.outfile = '%s.log' % os.path.basename(args[0]) + + sys.argv[:] = args + + prof = cProfile.Profile() + try: + try: + prof = prof.run('execfile(%r)' % (sys.argv[0],)) + except SystemExit: + pass + finally: + kg = KCacheGrind(prof) + kg.output(file(options.outfile, 'w')) + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/devtools/profilers/kcachegrind/usage.txt b/devtools/profilers/kcachegrind/usage.txt new file mode 100644 index 0000000..ce45d6b --- /dev/null +++ b/devtools/profilers/kcachegrind/usage.txt @@ -0,0 +1,4 @@ +To use this module, run your python code with lsprofcalltree.py and then +run kcachegrind on the output log generated. + +kcachegrind may be installed with the kdesk package |