Project Euler and other coding contests often have a maximum time to run or people boast of how fast their particular solution runs. With python, sometimes the approaches are somewhat kludgey - i.e., adding timing code to __main__
.
What is a good way to profile how long a python program takes to run?
I ran into a handy tool called SnakeViz when researching this topic. SnakeViz is a web-based profiling visualization tool. It is very easy to install and use. The usual way I use it is to generate a stat file with
%prun
and then do analysis in SnakeViz.The main viz technique used is Sunburst chart as shown below, in which the hierarchy of function calls is arranged as layers of arcs and time info encoded in their angular widths.
The best thing is you can interact with the chart. For example, to zoom in one can click on an arc, and the arc and its descendants will be enlarged as a new sunburst to display more details.
In Virtaal's source there's a very useful class and decorator that can make profiling (even for specific methods/functions) very easy. The output can then be viewed very comfortably in KCacheGrind.
A new tool to handle profiling in Python is PyVmMonitor: http://www.pyvmmonitor.com/
It has some unique features such as
Note: it's commercial, but free for open source.
I think that
cProfile
is great for profiling, whilekcachegrind
is great for visualizing the results. Thepyprof2calltree
in between handles the file conversion.To install the required tools (on Ubuntu, at least):
The result:
Following Joe Shaw's answer about multi-threaded code not to work as expected, I figured that the
runcall
method in cProfile is merely doingself.enable()
andself.disable()
calls around the profiled function call, so you can simply do that yourself and have whatever code you want in-between with minimal interference with existing code.A while ago I made
pycallgraph
which generates a visualisation from your Python code. Edit: I've updated the example to work with the latest release.After a
pip install pycallgraph
and installing GraphViz you can run it from the command line:Or, you can profile particular parts of your code:
Either of these will generate a
pycallgraph.png
file similar to the image below: