Profiling Python Code¶
The 'profile' module¶
This example shows how to use the cProfile Python
module to show script performance.
At release/scripts/modules/bpy/__init__.py#L68, the function call shows:
This example shows how a the function call can be profiled.
import cProfile
cProfile.run("import bpy; bpy.utils.load_scripts()", "blender.prof")
import pstats
p = pstats.Stats("blender.prof")
p.sort_stats("cumulative").print_stats(20)
This prints the top 20 cumulative functions.
Here is an example of what the output may look like.
45572 function calls (43669 primitive calls) in 0.243 seconds
Ordered by: cumulative time
List reduced from 1507 to 20 due to restriction <20>
ncalls tottime percall cumtime percall filename:lineno(function)
120/1 0.002 0.000 0.243 0.243 {built-in method builtins.exec}
1 0.000 0.000 0.242 0.242 <string>:1(<module>)
1 0.000 0.000 0.242 0.242 /src/blender/release/scripts/modules/bpy/utils/__init__.py:134(load_scripts)
126/20 0.002 0.000 0.192 0.010 <frozen importlib._bootstrap>:966(_find_and_load)
126/20 0.001 0.000 0.190 0.010 <frozen importlib._bootstrap>:939(_find_and_load_unlocked)
125/20 0.001 0.000 0.186 0.009 <frozen importlib._bootstrap>:659(_load_unlocked)
97/18 0.001 0.000 0.185 0.010 {built-in method builtins.__import__}
117/20 0.001 0.000 0.185 0.009 <frozen importlib._bootstrap_external>:656(exec_module)
213/20 0.000 0.000 0.182 0.009 <frozen importlib._bootstrap>:214(_call_with_frames_removed)
1231/162 0.001 0.000 0.169 0.001 <frozen importlib._bootstrap>:996(_handle_fromlist)
1 0.000 0.000 0.143 0.143 /src/blender/release/scripts/modules/bpy/utils/__init__.py:108(modules_from_path)
4 0.000 0.000 0.143 0.036 /src/blender/release/scripts/modules/bpy/utils/__init__.py:75(_test_import)
1 0.000 0.000 0.099 0.099 /src/blender/release/scripts/startup/bl_ui/__init__.py:23(<module>)
1071 0.013 0.000 0.072 0.000 {built-in method builtins.__build_class__}
1 0.000 0.000 0.057 0.057 /src/blender/release/scripts/modules/addon_utils.py:40(_initialize)
11 0.000 0.000 0.056 0.005 /src/blender/release/scripts/modules/addon_utils.py:258(enable)
991 0.007 0.000 0.050 0.000 /src/blender/release/scripts/modules/bpy_types.py:537(__new__)
4 0.000 0.000 0.041 0.010 /src/blender/release/scripts/modules/bpy/utils/__init__.py:202(test_register)
4 0.000 0.000 0.041 0.010 /src/blender/release/scripts/modules/bpy/utils/__init__.py:166(register_module_call)
117 0.001 0.000 0.040 0.000 <frozen importlib._bootstrap_external>:726(get_code)
Linux: perf + hotspot¶
On Linux, many Python builds have support for the perf tool. The profiling data it saves can be
loaded with Hotspot to produce interactive flame graphs.
On Ubuntu, these tools can be installed with:
Run the code & generate the profiling data, and then visualise with Hotspot:
$ env PYTHONPERFSUPPORT=1 perf record -F 63000 -g -o perf.data python yourscript.py
$ hotspot perf.data
The advantage of this approach is that you get an insight into both the C/C++ code and the Python code. The downside is that it's way more noisy than a Python-only profiler.
More info in the Python docs: support for the Linux perf profiler.
