7 routes42 sections324 units

Unit 6.5 · about 6 h

39 / 324

Profiling CPU and memory, and benchmarking honestly

Profiles locate expensive work; benchmarks test whether changing it helps. Mixing the two can turn profiler overhead, hidden queueing or a changed workload into an apparent improvement.

  • measure

You can now

  • Choose sampling, call instrumentation or allocation tracing to test a concrete bottleneck hypothesis.
  • Distinguish CPU cost, transient allocation peaks and retained Python memory from waiting and process RSS.
  • Build a correctness-checked benchmark with warm-up, repeated trials and raw results, then justify one optimization and a regime where it does not help.

Covers

  • Sampling versus instrumentation and wall versus CPU time
  • CPU profiles, allocation traces, RSS and memory retention
  • Warmup, repeated trials, workload control and raw results

Study, in this order

4 steps

  1. High Performance Python, 3rd edition: targeted profiling
    High Performance Python, 3rd edition

    Chapter 2: Profiling Efficiently (pp. 28-29), Using the cProfile Module (pp. 41-45), Using memory_profiler to Diagnose Memory Usage (pp. 53-60), Introspecting an Existing Process with PySpy (pp. 63-64), Unit Testing During Optimization to Maintain Correctness (pp. 73-76), Strategies to Profile Your Code Successfully (p. 77)

    Depth · Learn tool selection and output interpretation. Do not install every profiler or assume the book's tool versions support both 3.14 builds; execute the stdlib reproduction below.

  2. Call profiles are not benchmarks
    Python concurrency documentation

    Introduction to the profilers; Instant User's Manual: tottime and cumtime; What Is Deterministic Profiling?

  3. Temporary peaks versus retained allocations
    Python concurrency documentation

    Examples: Compute differences; Record the current and peak size of all traced memory blocks; API: get_traced_memory, reset_peak and Snapshot.compare_to

  4. Measuring the right thing, with less noise
    Algorithmica - Getting Accurate Results

    Getting Accurate Results: Measuring the Right Thing; Reducing Noise

    Depth · The examples are C++. Carry over the checks, not the code: a fixed input distribution, latency versus throughput, warm-up, frequency scaling, pinning and treating small differences as an A/B test.

Focus on

  • Sampling estimates where observed stacks spend time and can miss short events. Instrumentation records calls but perturbs execution. Choose a supported tool and timer for the hypothesis, not the prettiest report.
  • cProfile tottime excludes callees; cumtime includes them. Suspended async work and worker processes need separate interpretation; a request's wall time is not its CPU time.
  • tracemalloc sees traced Python allocations, not all native buffers or RSS. Compare snapshots after the same lifecycle stage for retention; reset the peak for transient allocations and record process memory separately.
  • Benchmark without profilers under matched input and offered load. Save correctness checks, hardware, Python build, worker count, start method, warm-up, all trials, throughput, latency distribution, rejection rate and queue depth. Include queue wait in end-to-end latency.

Reproduce closed-book

Write sum(list(range(n))) and sum(range(n)) for n = 100_000 and check both against n*(n-1)//2. Profile the materialized version with cProfile, then measure traced current and peak memory for each in fresh tracing sessions. The list version should have a larger temporary peak; do not require particular bytes or speedups. Retain 1,000 bytearray(1024) objects, compare snapshots before and after, clear the retaining list, collect garbage and compare again. Then benchmark both sum variants without tracing at small and larger n, with one warm-up and five trials each, saving CPU and full Python version/build with raw times. Explain an optimization's supported workload region rather than extrapolating to a service.

Traps

  • Timing task creation instead of awaiting completion, or hiding admission delay by starting the latency clock only after enqueue.
  • Calling high RSS a Python-object leak. Allocator retention and native memory can keep RSS high after traced allocations fall.
  • Reporting the fastest trial, changing total work, or benchmarking with cProfile or tracemalloc enabled.

Practice

The section mini-project covers this: CPU and retention diagnosis plus a controlled before/after pipeline benchmark with one justified improvement and one rejected optimization.

Self-test

  1. What does a high cumtime but low tottime suggest?

  2. Can a snapshot after a function returns reveal its freed temporary list?

  3. Why can low CPU usage coexist with high request latency?

  4. Why keep failures and rejections in a concurrency benchmark?

Completion criterion

Stop when

You can identify the materialization peak and retention site from evidence, preserve the result oracle, and present raw unprofiled trials with a workload-limited conclusion rather than a single best time.

Mark passed, then open 6.6 Only mark this when you can do it without notes.

Leads to

Comes after

Resources for this unit

  • Python concurrency documentation
    Python Software Foundationrequiredreference
    Use asyncio task groups, cancellation, queues and timeouts; concurrent.futures; multiprocessing; threading; and signal documentation to verify lifecycle and failure behavior.
  • High Performance Python, 3rd edition
    Micha Gorelick and Ian Ozsvald, O'Reillyrequiredimplementation
    Read Chapter 2 Profiling to Find Bottlenecks, Chapter 9 Asynchronous I/O, Chapter 10 The multiprocessing Module and Chapter 12 Using Less RAM, and use the companion code (https://github.com/mynameisfiber/high_performance_python_3e) as experiment starting points. Change the workloads and measure the regimes where concurrency helps, loses or only moves the bottleneck.
  • Algorithmica - Getting Accurate Results
    Sergey Slotinsupportreference
    Use Measuring the Right Thing and Reducing Noise for benchmark design: input distribution, latency versus throughput, warm-up, frequency scaling and pinning. The examples are C++; the checks transfer to Python.

Also in this section

  • AlgoMaster Concurrency
    AlgoMasterprimarycourse
    Study Concurrency 101; the Python units on threads, the GIL, multiprocessing, asyncio and concurrent.futures; synchronization primitives; concurrency challenges; locking strategies; and concurrency patterns. Then solve Bounded Buffer, Thread-Safe Blocking Queue, Thread-Safe Rate Limiter and Task Scheduler with Dependencies.
  • Operating Systems: Three Easy Pieces - concurrency
    Remzi and Andrea Arpaci-Dusseausupporttheory
    Read Chapters 26-33, from threads through event-based concurrency, for locks, condition variables, semaphores, concurrency bugs and event loops. Do selected homework only for a weak mechanism.
  • Docker guides
    Dockersupportimplementation
    Use the Python container guide and build best practices to run as non-root, pin dependencies, handle signals and test CPU and memory limits.
  • OpenTelemetry Python instrumentation
    OpenTelemetrysupportoperations
    Manually instrument one request so its structured logs, one low-cardinality metric and one trace share a correlation identity. Use the telemetry to locate one seeded fault.
  • Timeouts, retries, and backoff with jitter
    AWS Builders' Library, Marc Brookerrequiredoperations
    Read Timeouts, Retries and backoff, and Jitter for deadline scope, idempotency, one retry owner and bounded retry load. Interpret the five-layer example as three total attempts per layer, not three retries plus the initial attempt.
  • Site Reliability Engineering - overload and troubleshooting
    Googlerequiredoperations
    Read Chapter 21, The Pitfalls of Queries per Second, Client-Side Throttling, Utilization Signals, Handling Overload Errors and Conclusions. Read Chapter 12, Triage, Examine, Diagnose, Test and Treat, and Making Troubleshooting Easier for a service runbook. Skip datacenter load-balancing implementation details.
  • Liveness, Readiness, and Startup Probes
    Kubernetesrequiredreference
    Read Liveness probe, Readiness probe and Startup probe for the different health decisions and failure actions. Apply the contracts to a local service; do not install Kubernetes or configure a cluster.

Quick find

Search Michi

Type to search every route, section, unit, topic and resource.

Enter opens the first result Esc closes

Reference

Keyboard shortcuts

n
Continue to the first unit not passed
j / k
Next / previous unit
1 2 3
Toggle learned, practised, passed
/
Open search
?
Show this help
Esc
Close open panels