Writing benchmarks¶
The @mew.benchmark decorator¶
@mew.benchmark is the smallest unit: one function, one registered benchmark.
Bare or called forms are both valid:
@mew.benchmark
def bench_a(state): ...
@mew.benchmark(min_time=0.5, tags="sort")
def bench_b(state): ...
See mew.benchmark() for the full signature.
Per-benchmark options¶
All options are optional and map 1:1 to Google Benchmark concepts:
Option |
Effect |
|---|---|
|
Seconds Google Benchmark may spend stabilising the timing. |
|
Seconds spent warming caches before measurement. |
|
Force an exact iteration count (skips auto-tuning). |
|
Re-run the whole benchmark N times for variance metrics. |
|
Override reported time unit ( |
|
Report wall-clock instead of CPU time. |
|
The benchmark calls |
|
Use process-wide CPU time (multi-threaded benchmarks). |
|
When |
Defaults live in your pyproject.toml [tool.mew.benchmark_options] and are overridden by per-decorator options and by CLI flags.
See Configuration.
Naming¶
Auto-derived names mirror pytest node ids — path/to/file.py::qualname.
Override:
@mew.benchmark(name="custom_name")
def whatever(state): ...
Variants from @parametrize / @product always get a [label] suffix.
Common pitfalls¶
Setup inside the loop. The body of
for _ in state:is the measured region. Move data construction, file reads, and randomization outside the loop, or wrap them inState.pause().Optimised-away work. Python isn’t as aggressive as C++ here, but expressions whose results are never bound can still be elided. Assign to a variable or pass to
state.consume(...)when available.One decorator per function. Applying both
@benchmarkand@parametrizeto the same function raises aRuntimeErrorat import time. Split into two functions if you need both shapes.