When trying to optimize a web app, finding bottleneck is key (where we spent a lot of time). In other type of app it can be finding memory or CPU usage. This optimization should not be done to early, no need to optimize an unused or to-be-refactored piece of code.
Werkzeug have a build-in middleware that can profiles a request with python cProfile. It allow to follow exactly the execution graph of a request.
To enable this middleware just initialize your app with it:
Now each request will be profiled so make sure to remove this middleware when your optimization process is finished because it will drastically degrade your app response time!
Without any further options a cProfile output is printed:
It’s a good start but this is not really easy to read and to follow the call
graph. When developping a C/C++ app,
callgrind (the reference
call-graph profiler) provide a very nicer third party graphical app called
kcachegrind (or qcachegrind for
the Qt version). It can be installed on Mac via
brew. Here is what a debug
session looks like:
The problem which is not really one is that the call-graph session must be a
callgrind one not a cProfile. This can be easily solved by using a small python
script called pyprof2calltree
pip install it in your virtualenv).
The Werkzeug middleware must be initialized with the
profile_dir option in
order to store profiling session as a file (beware, if a directory is
specified, it must exist or an error is raised). Then the cProfile output can
be converted using
callgrind.* file can now be opened with kcachegrind. To get
callgraph ploting work the
dot binary must be installed.
You may experience
$PATH issue like me on Mac when opening kcachegrind
directly from the Finder, to solves this just open it from a terminal.