Quick start¶
1. Define a case¶
Create benchmarks/bench_hashing.py:
import hashlib
from benchbro import Case, system
@system(scope="session")
def salt() -> bytes:
return b"-fixture"
case = Case(
name="hashing",
case_type="cpu",
metric_type="time",
tags=["fast", "core"],
)
@case.input()
def payload() -> bytes:
return b"benchbro"
@case.benchmark()
def sha256(payload: bytes, salt: bytes) -> str:
return hashlib.sha256(payload + salt).hexdigest()
Inputs and systems are injected by parameter name. The input supplies data for the case; the session-scoped system supplies one reusable dependency.
2. Run it¶
With no target, BenchBro searches benchmarks/**/*.py. You can also pass a module,
file, or directory explicitly:
The first normal run creates .benchbro/baseline.local.json. Later runs compare
against it automatically.
3. Save reports¶
Reports are opt-in:
$ uv run benchbro run \
--output-json artifacts/current.json \
--output-csv artifacts/current.csv \
--output-md artifacts/current.md
4. Tighten the experiment¶
Start with defaults, then tune measurement only when the benchmark calls for it:
case = Case(
name="hashing",
adaptive=True,
min_repeats=5,
repeats=100,
target_relative_margin_pct=2.0,
max_time_s=10.0,
)
Adaptive sampling stops once the requested precision is reached, or when its time or repeat budget is exhausted. Read Reliable measurements before using a threshold as a performance gate.