Profiling¶
profile¶
Python has a profile
module to help you find the places in the
code where the time is spent.
Let’s say you have a script script.py
that you want to run through the
profiler. This is what you do:
>>> import profile
>>> profile.run('import script', 'prof')
This will run your script and generate a profile in the file prof
.
You can also generate the profile by inserting a line like this in
your script:
...
import profile
profile.run('atoms.get_potential_energy()', 'prof')
...
To analyse the results, you do this:
>>> import pstats
>>> pstats.Stats('prof').strip_dirs().sort_stats('time').print_stats(20)
Tue Oct 14 19:08:54 2008 prof
1093215 function calls (1091618 primitive calls) in 37.430 CPU seconds
Ordered by: internal time
List reduced from 1318 to 20 due to restriction <20>
ncalls tottime percall cumtime percall filename:lineno(function)
37074 10.310 0.000 10.310 0.000 :0(calculate_spinpaired)
1659 4.780 0.003 4.780 0.003 :0(relax)
167331 3.990 0.000 3.990 0.000 :0(dot)
7559 3.440 0.000 3.440 0.000 :0(apply)
370 2.730 0.007 17.090 0.046 xc_correction.py:130(calculate_energy_and_derivatives)
37000 0.780 0.000 9.650 0.000 xc_functional.py:657(get_energy_and_potential_spinpaired)
37074 0.720 0.000 12.990 0.000 xc_functional.py:346(calculate_spinpaired)
...
...
The list shows the 20 functions where the most time is spent. Check the pstats documentation if you want to do more fancy things.
Tip
Since the profile
module does not time calls to C-code, it
is a good idea to run the code in debug mode - this will wrap
calls to C-code in Python functions:
$ python3 -d script.py
Tip
There is also a quick and simple way to profile a script:
$ pyhton script.py --profile=prof
This will produce a file called prof.0000
where 0000
is the
rank number (if your run the script in parallel, there will be one
file per rank).
Use:
$ python3 script.py --profile=-
to write the report directly to standard output.