Profiling
Contents
Profiling#
BB1000 Programming in Python KTH
Learning Goals#
to profile programs
to do line-by-line profiling
to profile short code pieces
layout: false
Profiling#
As Python programs can be potentially slow it is important to be able to identify the bottlenecks of the code
The most important rule is: never optimize code without profiling
Even very experience programmers guess wrong
Example#
#hello_goodbye.py
import time
def hello():
time.sleep(1)
print("Hello")
def goodbye():
time.sleep(2)
print("Goodbye")
def main():
hello()
goodbye()
if __name__ == "__main__":
main()
>>> import hello_goodbye
>>> hello_goodbye.main()
Hello
Goodbye
Analyis: the cProfile module#
>>> import cProfile
>>> cProfile.run('hello_goodbye.main()')
Hello
Goodbye
10 function calls in 3.003 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 3.003 3.003 <string>:1(<module>)
1 0.000 0.000 3.003 3.003 hello_goodbye.py:11(main)
1 0.000 0.000 1.001 1.001 hello_goodbye.py:3(hello)
1 0.000 0.000 2.002 2.002 hello_goodbye.py:7(goodbye)
1 0.000 0.000 3.003 3.003 {built-in method builtins.exec}
2 0.000 0.000 0.000 0.000 {built-in method builtins.print}
2 3.003 1.502 3.003 1.502 {built-in method time.sleep}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
Statistics
number of times a function was called
time spent per function
time spent per function including subcalls (cumulative)
Line profiling#
Rather than knowing how much time is spent in the function we may want to know line-by-line what happens
The line_profiler
module#
Use the third-party package
line_profiler
to get timing statistics line-by-lineInstall with
$ pip install line_profiler
The
line-profiler
package contains a scriptkernprof
which is used to execute your file (instead ofpython
)kernprof
defines a decorator which you can use to analyze the function in question
The steps are:
Decorate the function you want to time with the
@profile
decoratorExecute the script with the
kernprof
script
$ kernprof -l hello_goodbye.py
Hello
Goodbye
Wrote profile results to hello_goodbye.py.lprof
$ python -m line_profiler hello_goodbye.py.lprof
Timer unit: 1e-06 s
Total time: 3.00327 s
File: hello_goodbye.py
Function: main at line 11
Line # Hits Time Per Hit % Time Line Contents
==============================================================
11 @profile
12 def main():
13 1 1001139 1001139.0 33.3 hello()
14 1 2002132 2002132.0 66.7 goodbye()
Profiling code snippets#
The timeit module executes a single statement $10^6$ times
An optional setup parameter
Report the time
import timeit
print(timeit.timeit('math.sqrt(2.0)', setup='import math'))
0.288702964783
print(timeit.timeit('sqrt(2.0)', setup='from math import sqrt'))
0.2072930336
Summary#
profile
module for function-level profiling your codeline_profiler
module for line-level profiling your codetimeit
module for timing short code snippets
Do not ever optimize your code without profiling