0Pricing
Python Academy · Lesson

Profiling with cProfile and line_profiler

Find CPU hotspots with cProfile and line-by-line profiling.

Profiling with cProfile and line_profiler is a free Python Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Python Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why Profile?

Profiling identifies which functions consume the most time, guiding optimisation efforts. Always profile before optimising — never guess.

import cProfile

def slow():
    total = 0
    for i in range(1_000_000):
        total += i
    return total

cProfile.run("slow()")

Running cProfile from CLI

Profile an entire script without modifying it: python -m cProfile -s cumtime script.py. Sort by cumtime, tottime, or calls.

# python -m cProfile -s cumtime my_script.py
#
# ncalls  tottime  percall  cumtime  percall filename:lineno(function)
#   1000    0.500    0.001    2.100    0.002 utils.py:10(process)

cProfile in Code

Create a cProfile.Profile, enable/disable it, then print stats with pstats.

import cProfile, pstats, io

pr = cProfile.Profile()
pr.enable()

# ... code to profile ...

pr.disable()
stream = io.StringIO()
ps = pstats.Stats(pr, stream=stream).sort_stats("cumulative")
ps.print_stats(10)   # top 10
print(stream.getvalue())

pstats Filtering

Filter profiler output to a specific module or function name pattern using print_stats(pattern).

import cProfile, pstats

cProfile.run("my_function()", "profile.out")
stats = pstats.Stats("profile.out")
stats.sort_stats("tottime")
stats.print_stats("mymodule")   # only mymodule functions

line_profiler

line_profiler shows execution time per line, not just per function — essential for finding the hot line inside a function.

# pip install line_profiler
# Decorate target function:
from line_profiler import profile

@profile
def process(data):
    result = []
    for item in data:          # <- which line is slow?
        result.append(item*2)
    return result

# Run: kernprof -l -v script.py

kernprof CLI

kernprof -l script.py runs the script with line profiling enabled; -v displays the report immediately.

# kernprof -l -v script.py
#
# Line #  Hits  Time  Per Hit  % Time  Line Contents
# ======================================================
#     4    1  2.0   2.0       1.0    result = []
#     5  1000  120.0  0.1     60.0    for item in data:
#     6  1000   80.0  0.1     39.0        result.append(item*2)

Profiling in Jupyter

Jupyter provides %prun (cProfile) and %lprun (line_profiler) magic commands.

# In a Jupyter cell:
# %prun -s cumulative my_function(data)

# %load_ext line_profiler
# %lprun -f my_function my_function(data)

Identifying Hotspots

Focus on the functions with the highest cumulative time (the whole chain) and the highest total time (the function itself, excluding callees).

# cumtime = total time including callees (find root cause)
# tottime = time in function itself (find where work happens)
#
# Optimise the function with highest tottime first

Avoiding Premature Optimization

Profile first, then optimise the measured bottleneck. Common Python speedups: use built-ins, move loops to NumPy, cache repeated lookups, or call C via ctypes/cffi.

# Before optimising:
# profile shows: process_row() 95% of time

# Speedup: vectorise with NumPy
import numpy as np
arr = np.array(data)
result = arr * 2   # 100x faster than Python loop

py-spy: Sampling Profiler

py-spy profiles running processes without modifying code — attach to a live PID.

# pip install py-spy

# Profile for 30 s and show flamegraph:
# py-spy top --pid 12345
# py-spy record -o profile.svg --pid 12345 --duration 30

Benchmarking with timeit

Use timeit for micro-benchmarks of specific expressions.

import timeit

result = timeit.timeit(
    "[x*2 for x in range(1000)]",
    number=10_000
)
print(f"{result:.3f} s for 10k runs")

Quick Check

What does tottime show in a cProfile report?

Recap

Use cProfile to find slow functions and line_profiler to find the slow line. Profile with -s cumtime to find root causes. Optimise only proven hotspots — use NumPy vectorisation, caching, or C extensions for the biggest wins.

Frequently asked questions

Is the “Profiling with cProfile and line_profiler” lesson free?

Yes — the full text of “Profiling with cProfile and line_profiler” is free to read here on the web, and the Python Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Python Academy course, upgrade to CoddyKit PRO.

What will I learn in “Profiling with cProfile and line_profiler”?

Find CPU hotspots with cProfile and line-by-line profiling. You practise Python Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Python Academy?

No prior experience is required. Python Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Profiling with cProfile and line_profiler” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Python Academy lesson?

Yes. Every Python Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. CPython Reference Counting
  2. The Garbage Collector and Cyclic References
  3. Profiling with cProfile and line_profiler
  4. Memory Profiling with tracemalloc
← Back to Python Academy