cProfile module

Updated April 12, 2026 · Modules
profiling performance stdlib

Overview

cProfile is a C extension module that provides deterministic profiling for Python code. It is based on lsprof and has much lower overhead than the pure Python profile module, making it suitable for profiling long-running programs.

The module ships with the standard library, so no installation is required. Use cProfile when you need to understand where your code spends its time.

Quick Start

The fastest way to profile a piece of code is with cProfile.run():

import cProfile

cProfile.run('re.compile("foo|bar")')

This prints profile output showing function call counts, timing data, and source locations. By default, output is sorted by standard name ('stdname').

The Profile Class

For more control, instantiate Profile directly:

import cProfile

pr = cProfile.Profile()
pr.enable()
# ... code you want to profile ...
pr.disable()
pr.print_stats()

Key Methods

MethodDescription
enable()Start collecting profiling data
disable()Stop collecting profiling data
create_stats()Stop collecting and record results internally
print_stats(sort=-1)Create a Stats object and print to stdout
dump_stats(filename)Write profile data to a file
runcall(func, *args, **kwargs)Profile a single function call
runctx(cmd, globals, locals)Profile code with explicit namespace dicts

Context Manager

Python 3.8 introduced context manager support:

import cProfile

with cProfile.Profile() as pr:
    result = some_function()
    pr.print_stats()

This ensures profiling is always stopped, even if an exception occurs.

Saving and Analyzing Profile Data

To save profile output to a file for later analysis:

import cProfile

cProfile.run('some_function()', 'profile.out')

Load that file with pstats.Stats:

import pstats
from pstats import SortKey

ps = pstats.Stats('profile.out')
ps.strip_dirs()   # remove leading paths from filenames
ps.sort_stats(SortKey.TIME)
ps.print_stats(10)   # top 10 lines

Merging Profile Runs

You can combine multiple profile files:

ps = pstats.Stats('profile1.out')
ps.add('profile2.out')
ps.print_stats()

Inspecting Callers and Callees

To see which functions called a specific function:

ps.print_callers('my_function')

To see what a function called:

ps.print_callees('my_function')

Sort Options

Import sort keys from pstats:

from pstats import SortKey
StringSortKeyWhat it sorts
'time'SortKey.TIMEInternal time (excludes subfunction time)
'cumulative'SortKey.CUMULATIVECumulative time in function + subfunctions
'calls'SortKey.CALLSCall count
'pcalls'SortKey.PCALLSPrimitive call count (excludes recursive)
'name'SortKey.NAMEFunction name
'filename'SortKey.FILENAMEFile name
'stdname'SortKey.STDNAMEStandard name (default sort)

Multi-level sorting is supported by passing a tuple:

ps.sort_stats(SortKey.TIME, SortKey.CUMULATIVE)

Numeric Sort Codes (Legacy)

For backward compatibility, numeric values still work: -1 = stdname, 0 = calls, 1 = time, 2 = cumulative.

Output Columns

The profile table contains these columns:

ColumnMeaning
ncallsNumber of calls (shown as total/primitive for recursive functions)
tottimeTime spent in the function, excluding subfunction calls
percall (tottime)tottime / ncalls
cumtimeCumulative time in the function + all subfunctions
percall (cumtime)cumtime / primitive_calls
filename:lineno(function)Source location and function name

Command-Line Usage

Profile an entire script from the terminal:

python -m cProfile -s cumulative myscript.py

Save output to a file:

python -m cProfile -o profile.out -s time myscript.py

Launch an interactive browser:

python -m pstats profile.out

Profile a module instead of a script:

python -m cProfile -m mymodule arg1 arg2

Limitations

A few things to keep in mind when using cProfile:

Clock resolution is ~0.001 seconds. Timing accuracy is limited to this granularity. For precise benchmarks, use timeit instead.

The profiler adds overhead to Python code but not C functions. This makes C code appear proportionally faster than it actually is. Results are useful for relative comparisons within Python code, not absolute measurements.

Profile files are not portable across Python versions or operating systems. Do not rely on compatibility when sharing profile data.

The default sort is 'stdname', not 'cumulative'. Many users expect cumulative time by default and find this surprising.

See Also