Profiling Python Like a Boss
zapier.com
zapier.com
$ python -mcProfile -o foo.pstats foo.py
This will run your script (foo.py) inside of the profiler and save the profile to the file foo.pstats once the script is done.Once you have a pstats file, you can do some interesting things with it. You can load it into an interactive pstats session with this:
$ python -mpstats foo.pstats
This will allow you to sort and display the profile data in a number of ways.You can also use the third-party gprof2dot script[1] to turn the pstats file into a GraphViz dot file, and thence into a visualization of your code's performance. For example:
$ gprof2dot.py -f pstats foo.pstats | dot -Tpdf -o foo.pdf
That will turn your foo.pstats file into a PDF. I like the PDF format here because it is vectorized, renders quickly (more quickly than SVG, at least), and you can search for specific text in it (which is useful if you have a large profile and want to find a specific function).The result ends up looking like this: https://f.cloud.github.com/assets/150329/1570121/5713f02c-50...
Django middleware to turn on/off and collect & store the profile data, and then a developer interface to read the stored profiles and render in SVG using pydot.
https://github.com/phleet/flask_debugtoolbar_lineprofilerpan... (includes screenshot)
or https://github.com/dmclain/django-debug-toolbar-line-profile...
It provides a very intuitive way to figure out where, exactly, your view is slow. I know the Chrome and Firefox teams are both hard at work on building more robust profiling tools, but I would love to see them integrate something for JavaScript that's this easily accessible.
The best sales pitch for profiling there is, perhaps. :)
def inner(func):
def nothing(*args, **kwargs):
return func(*args, **kwargs)
return nothing
Be simplified to: def inner(func):
return funcWith IPython, you can simply write:
%time result = expensive_function()
and the time it takes to execute expensive_function() is printed out to the console. You can also directly substitute %timeit or %prun for %time to use loops for the timer or to invoke built-in profiler. No need to write any of your own boilerplate!For profiling, I've occasionally swapped out some key function with odd characteristics with one runs in a profile. So you can create a new Profiler instance, and patch your weird function to instead call profiler.runcall(func). After you've tested it a few times, you swap back to the old version and dump the stats.
If you have multiple proxying layers, multiple processes etc. a useful option is to make e.g. Apache save the request time in the main or another log file. This is the CustomLog %D option. Then you can easily find out that e.g. /foo/bar requests take so and so much on average, with 95% below this number, perhaps even doing real-time warning when they start to increase.
Question. It's been a while since I used them, but what happens when you use cProfile or kernprof in multithreaded / forking code? I vaguely recall wiring up a custom trace event logger via sys.settrace() to work around this.