public
Last active

Profile method decorator in Python showing a graphical (.svg) representation (as well as a text-based representation) as the output.

  • Download Gist
profiling.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
import pstats
import sys
import subprocess
import os
try:
import cProfile as profile
except ImportError:
import profile
 
 
def profile_method(filename, rows=50, sort=(('cumul',), ('time',)), show_graph=False):
'''
Decorator to profile the decorated function or method.
To use:
@profile_method('out.prof', show_graph=True)
def my_func_to_profile():
...
my_func_to_profile()
 
 
Depends on:
 
- Graphviz to generate the graph: http://www.graphviz.org/ must be installed with the GRAPHVIZ_DOT environment variable pointing to dot.exe.
 
- gprof2dot: http://gprof2dot.jrfonseca.googlecode.com/git/gprof2dot.py must be in the PYTHONPATH).
 
- desktop: optional: https://pypi.python.org/pypi/desktop if available will open the generated .svg automatically (a viewer must be properly registered)
 
:param int rows:
How many rows of data to print.
:param tuple sort:
How to sort the stats of the printed data.
Options available from:
stats = pstats.Stats(prof)
print(stats.get_sort_arg_defs().keys())
:param bool show_graph:
Whether a graph should be generated. Note: the computer should have an .svg viewer
associated to the extension so that the file is properly opened.
'''
 
def wrapper(method):
def inner(*args, **kwargs):
prof = profile.Profile()
result = prof.runcall(method, *args, **kwargs)
 
prof.dump_stats(filename)
 
if show_graph:
_show_graph(filename)
 
# Show text output regardless of showing graph.
tup_sort = sort
s = tup_sort[0]
if isinstance(s, str):
tup_sort = [tup_sort]
 
stats = pstats.Stats(prof)
for s in tup_sort:
stats.strip_dirs().sort_stats(*s).print_stats(int(rows))
 
return result
return inner
return wrapper
 
 
def _show_graph(filename):
'''
Creates an .svg from the profile generated file and opens it (a proper association to .svg
files must be already defined in the machine).
@param str filename:
This is the file generated from profile_method.
'''
import gprof2dot
initial = sys.argv[:]
output_filename = filename + '.dot'
sys.argv = ['', '-o', output_filename, '-f', 'pstats', filename]
try:
gprof2dot.Main().main()
finally:
sys.argv = initial
 
try:
dot = os.environ['GRAPHVIZ_DOT']
except KeyError:
raise AssertionError('The GRAPHVIZ_DOT environment variable must be defined to show graph.')
 
assert os.path.exists(dot), 'Expected: %s to exist and point to dot.exe' % dot
subprocess.call([dot, '-Tsvg', '-O', output_filename])
 
print('Opening svg created at:', os.path.realpath((output_filename + '.svg')))
try:
import desktop
except:
pass
else:
desktop.open(output_filename + '.svg')

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.