Source code for arsenal.profiling

#!/usr/bin/env python

import os
import sys
import pstats
import cProfile
from arsenal.terminal import colors
from contextlib import contextmanager

[docs]@contextmanager def profiler(use='cprofile', filename='out.prof'): if use == 'yep': # pragma: no cover import yep yep.start(filename) if use == 'cprofile': # pragma: no cover #import cProfile prof = cProfile.Profile() prof.enable() try: yield finally: if use == 'yep': # pragma: no cover yep.stop() print(colors.yellow % 'wrote: %s' % filename, '(use `google-pprof` to view)') # google-pprof --text /bin/ls imitation.prof # google-pprof --evince /bin/ls imitation.prof # google-pprof --web /bin/ls --web imitation.prof if use == 'cprofile': # pragma: no cover #import pstats prof.disable() prof.dump_stats(filename) #pstats.Stats(filename).strip_dirs().sort_stats('time').print_stats() print(colors.yellow % 'wrote: %s' % filename, '(use `gprof-viz` to view)')
# TODO: # - maybe we should delete the `out` tempfile # - I don't like that this currently makes a system call to open the image... # - gprof2dot is on the pythonpath we should be able to avoid the system call
[docs]def profile_viz(cmd, global_dict=None, local_dict=None, img='profile.png', out='profile.tmp', noctx=False): "Run gprof2dot on the output for profiling." if noctx: cProfile.run(cmd, out) else: if local_dict is None and global_dict is None: call_frame = sys._getframe().f_back local_dict = call_frame.f_locals global_dict = call_frame.f_globals cProfile.runctx(cmd, global_dict, local_dict, out) stats = pstats.Stats(out) stats.strip_dirs() # Clean up filenames for the report stats.sort_stats('cumulative') # sort by the cumulative time stats.print_stats() # for more on the viz check out: http://code.google.com/p/jrfonseca/wiki/Gprof2Dot os.system('gprof2dot.py -f pstats %s | dot -Tpng -o %s && eog %s &' % (out, img, img))
#def kcachegrind(cmd, out='profile.kgrind'): # from arsenal.profiling.lsprofcalltree import KCacheGrind # p = cProfile.Profile() # p.run(cmd) # # Get the stats in a form kcachegrind can use and save it # k = KCacheGrind(p) # with file(out, 'wb') as f: # k.output(f) # os.system("kcachegrind %s &" % out)
[docs]def main(): from optparse import OptionParser parser = OptionParser() parser.allow_interspersed_args = False parser.add_option('-o', '--outfile', dest="outfile", help="Save stats to <outfile>", default='/tmp/profile.tmp') if not sys.argv[1:]: parser.print_usage() sys.exit(2) (options, args) = parser.parse_args() #viz = kcachegrind viz = profile_viz sys.path = [os.getcwd()] + sys.path if len(args) > 0: sys.argv[:] = args sys.path.insert(0, os.path.dirname(sys.argv[0])) viz('execfile(%r)' % sys.argv[0], out=options.outfile) else: parser.print_usage() return parser
if __name__ == '__main__': main()