Warming up the neural circuits...
By the end of this chapter you will:
Performance intuition is unreliable. Teams often optimize the wrong function, the wrong layer, or the wrong bottleneck.
The rule is strict: measure first, optimize second.
import timeit
stmt = "sum(i*i for i in range(1000))"
result = timeit.timeit(stmt, number=1000)
print(result)Keep benchmark setup controlled and compare equivalent logic.
python -m cProfile -o out.prof app.pyThen visualize with snakeviz or inspect in pstats.
py-spy is useful for sampling live processes with lower runtime overhead.
Order of impact:
Do not start at level 4.
from functools import lru_cache
@lru_cache(maxsize=512)
def fib(n: int) -> int:
if n < 2:
return n
return fib(n - 1) + fib(n Escalation options:
Only escalate after profiling validates the bottleneck.
Warm up code paths, benchmark multiple runs, and separate setup cost from measured body. Without this, numbers are noise.
| Mistake | Symptom | Fix |
|---|---|---|
| Benchmarking different behavior and comparing numbers | False conclusions | Benchmark equivalent logic only |
| Optimizing cold paths | No user-visible improvement | Profile end-to-end first |
| Over-caching mutable/non-deterministic operations | Stale or wrong results | Cache only pure deterministic functions |
| Ignoring memory while optimizing CPU | New OOM incidents | Track CPU and memory together |
| Premature low-level micro-optimizations | Complex code with tiny gains | Follow optimization ladder |
Square 1000 integersMeasured timings for both approachespython -m cProfile app.pyTop hotspot function nameRepeated lookup in list of recordsAsymptotic improvement and faster run timelru_cache to deterministic normalization helper.Function normalizing country codesRepeated calls avoid recomputationBefore/after benchmark dataRoot cause and better next actionBeginner:
"Why is profiling more important than intuition?"
Because real bottlenecks are often different from what developers expect; profiling provides evidence.
"When should you use lru_cache?"
For deterministic pure functions with repeated inputs where memory tradeoff is acceptable.
Senior:
"How do you design a performance improvement process for a team?"
Define baseline metrics, profile representative workloads, prioritize high-impact hotspots, and enforce benchmark checks in CI for critical paths.
"How do you avoid performance regressions over time?"
Keep benchmark suites, capture key latency/throughput metrics, and alert on regression thresholds.
timeit for micro cases and profilers for system hotspots.Need speed? -> measure first
Need hotspot? -> cProfile/py-spy
Need biggest gains? -> algorithm/data structure first
Need repeated pure result reuse? -> lru_cacheWhat is the first step in a reliable optimization workflow?
only pure functions; be mindful of memory footprint.