Profiling in Python
blog.thehumangeo.com
blog.thehumangeo.com
https://taoofmac.com/space/blog/2014/07/07/2030
Here's a handy command line for it:
https://github.com/rcarmo/sushy/blob/master/Makefile#L86
...and a large diagram of a profiling session:
https://github.com/rcarmo/sushy/blob/master/pages/blog/2015/...
With the class you could easily change the ordering without having to re-run the command (very useful when the command take several minutes). Also allows you to apply filters (cut the number of lines or apply regular expression) to the output. Usually I filter for the one/two file where most of my custom code is and I check for the hotspot; this remove all Django related calls. Then I select a good candidate for optimization and I dig that functions looking at the code (restrictions are useful in many way). It is a long process, but much less painful than you could expect. But probably it should have a well designed interface to make it easier to use.
[0] https://docs.python.org/2/library/profile.html#the-stats-cla...
Having some background knowledge of how Python implements some of its types can also be useful when debugging performance issues. For instance, knowing that the Python list type is implemented using a variable-length array of object references (rather than a linked-list) will help one figure out why inserting in the front or middle of a Python list is slow.
https://docs.python.org/2/faq/design.html#how-are-lists-impl...
It makes it pretty obvious where time is spent, and every piece in the flame graph (and in the list of routines below) is a link to the source code, with each line annotated by number of calls and time spent.
% cat > l.py
@profile
def slow_func():
for i in xrange(1048576):
continue
return -1
@profile
def fast_func():
for i in xrange(10):
continue
return -1
@profile
def the_func():
for i in xrange(10):
slow_func()
fast_func()
if __name__ == "__main__":
the_func()
% kernprof -l l.py
% python -m line_profiler l.py.lprof
Timer unit: 1e-06 s
Total time: 5.21814 s
File: l.py
Function: slow_func at line 1
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 @profile
2 def slow_func():
3 10485770 2644263 0.3 50.7 for i in xrange(1048576):
4 10485760 2573875 0.2 49.3 continue
5
6 10 5 0.5 0.0 return -1
Total time: 8.9e-05 s
File: l.py
Function: fast_func at line 8
Line # Hits Time Per Hit % Time Line Contents
==============================================================
8 @profile
9 def fast_func():
10 110 61 0.6 68.5 for i in xrange(10):
11 100 26 0.3 29.2 continue
12
13 10 2 0.2 2.2 return -1
Total time: 10.5501 s
File: l.py
Function: the_func at line 14
Line # Hits Time Per Hit % Time Line Contents
==============================================================
14 @profile
15 def the_func():
16 11 3 0.3 0.0 for i in xrange(10):
17 10 10549853 1054985.3 100.0 slow_func()
18 10 203 20.3 0.0 fast_func()