Profile a Python script with cProfile

Find expensive functions with cProfile, sort saved statistics with pstats, and choose line profiling or timeit for more focused analysis.

Best practices
Python programming and application logging

Start with python3 -m cProfile -s cumulative myscript.py to see which functions account for the most cumulative time. Use the results to choose where to investigate, then measure a representative workload before deciding whether a change helped.

Profile from the command line

python3 -m cProfile -s cumulative myscript.py

The report includes:

Column Meaning
ncalls Number of calls; recursive functions may show total and primitive calls
tottime Time inside the function, excluding subcalls
First percall tottime divided by total calls
cumtime Time in the function and its subcalls
Second percall cumtime divided by primitive calls
filename:lineno(function) Function location

High cumulative time identifies an expensive call path. High internal time can identify a function doing substantial work itself. These are function-level measurements, not a breakdown of every source line.

Profile a specific call

import cProfile

def my_function():
    return sum(value * value for value in range(10_000))

cProfile.run("my_function()")

For code that already holds a function reference and arguments, cProfile.Profile().runcall(my_function) avoids expressing the call as a string.

Save and inspect statistics

python3 -m cProfile -o profile_stats myscript.py

Then inspect the file:

import pstats

stats = pstats.Stats("profile_stats")
stats.sort_stats("cumulative").print_stats(20)
stats.sort_stats("time").print_stats(20)

The first listing ranks cumulative time; the second ranks internal time. Keep workload, interpreter, and environment comparable when comparing runs. A profile is not a machine-independent performance score.

Inspect individual lines

The third-party line_profiler package can measure selected functions line by line:

python3 -m pip install line_profiler
kernprof -l -v myscript.py

In the script, mark the target function with @profile for the kernprof workflow. That decorator is supplied by the tool; it is not a built-in decorator available in an ordinary Python run. Consult the installed version's documentation if you prefer an explicit import workflow.

FAQ

How much overhead does profiling add? It depends on the workload and profiler. There is no reliable universal 10–30% overhead figure. Treat instrumented timing as diagnostic evidence and validate important improvements without the profiler.

When should I use timeit? Use it to compare small pieces of code through repeated executions. cProfile helps locate expensive functions in a larger run.

Can I visualize the output? Tools such as SnakeViz and gprof2dot consume profiling statistics. They make call paths easier to explore, but do not eliminate measurement overhead or make the workload representative.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting