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 functionsline_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.pykernprof 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 firstAvoiding 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 looppy-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 30Benchmarking 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
- CPython Reference Counting
- The Garbage Collector and Cyclic References
- Profiling with cProfile and line_profiler
- Memory Profiling with tracemalloc