The standard library has shipped two tracing profilers for a long time. cProfile is written in C, and profile is written in Python and does the same job more slowly. Since Python 3.15, importing profile reports a deprecation warning. The module still works, but it is scheduled for removal in Python 3.17.
The following script profiles a function with the profile module:
import profile
def work():
return sum(i * i for i in range(200000))
profile.run('work()', sort='tottime')
The warning appears without any extra flag, because Python shows a deprecation warning that comes from the file being run:
main.py:1: DeprecationWarning: The profile module is deprecated and will be removed in Python 3.17. Use profiling.tracing (or cProfile) for tracing profilers instead.
import profile
200007 function calls in 0.248 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.114 0.114 0.226 0.226 :0(sum)
200001 0.111 0.000 0.111 0.000 main.py:5(<genexpr>)
1 0.022 0.022 0.022 0.022 :0(setprofile)
1 0.000 0.000 0.248 0.248 profile:0(work())
1 0.000 0.000 0.226 0.226 :0(exec)
1 0.000 0.000 0.226 0.226 main.py:4(work)
1 0.000 0.000 0.226 0.226 <string>:1(<module>)
0 0.000 0.000 profile:0(profiler)
The replacement is profiling.tracing, a module added in Python 3.15. Its run and runctx functions take the same arguments as the ones in profile, so the import is the only line that changes.
The cProfile module is not deprecated. It is an alias for profiling.tracing, and the documentation states that code using import cProfile will keep working without modification in all future Python versions.
import profiling.tracing
def work():
return sum(i * i for i in range(200000))
profiling.tracing.run('work()', sort='tottime')
Output:
200006 function calls in 0.044 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.025 0.025 0.044 0.044 {built-in method builtins.sum}
200001 0.019 0.000 0.019 0.000 main.py:5(<genexpr>)
1 0.000 0.000 0.044 0.044 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.044 0.044 main.py:4(work)
1 0.000 0.000 0.044 0.044 <string>:1(<module>)
The same script now runs in 0.044 seconds instead of 0.248. Both reports measure the same work, and the difference is the cost of the profiler itself.
The reports also label built-in functions differently, and the rows belonging to the profiler itself change, so a script that reads these reports needs adjusting.
Leave a Comment
Cancel reply