Benchmark library and CLI
Project description
benchbro
benchbro is a Python benchmarking library and CLI with pytest-style discovery and rich terminal output.
Quick start
Install dependencies:
uv sync --group dev
Create benchmark cases in any importable module:
from benchbro import Case
case = Case(name="hashing", case_type="cpu", metric_type="time", tags=["fast", "core"])
@case.input()
def payload() -> bytes:
return b"benchbro"
@case.benchmark()
def sha1(payload: bytes) -> str:
import hashlib
return hashlib.sha1(payload).hexdigest()
@case.benchmark()
def sha256(payload: bytes) -> str:
import hashlib
return hashlib.sha256(payload).hexdigest()
Regression thresholds default to 50.0 percent warning and 100.0 percent error at the case level, and can be overridden per benchmark:
case = Case(name="hashing", warning_threshold_pct=5.0, regression_threshold_pct=10.0)
@case.benchmark(warning_threshold_pct=2.0, regression_threshold_pct=3.0)
def critical_path(payload: bytes) -> str:
...
Comparison metric can be configured at case-level and benchmark-level:
case = Case(name="hashing", comparison_metric="p95_s")
@case.benchmark(comparison_metric="median_s")
def critical_path(payload: bytes) -> str:
...
Valid comparison metrics:
- time:
median_s(default),mean_s,iqr_s,p95_s,stddev_s,ops_per_sec - memory:
peak_alloc_bytes(default),net_alloc_bytes,peak_alloc_bytes_max
GC is disabled during measured iterations by default. To keep the interpreter GC behavior unchanged, set:
Case(name="hashing", gc_control="inherit")
Run benchmarks:
uv run benchbro --repeats 10 --warmup 2
When no target is provided, benchbro discovers benchmarks from:
benchmarks/**/*.py(relative to repo root)
You can configure discovery in pyproject.toml:
[tool.benchbro.ini_options]
benchmark_paths = ["benchmarks"]
file_pattern = ["bench_*.py", "*_bench.py", "*benchmark.py", "*benchmarks.py"]
benchmark_paths: directories to scan when no CLI target is providedfile_pattern: glob pattern(s) for benchmark file names in directory discovery
benchbro compares against the baseline by default (.benchbro/baseline.local.json).
If the baseline is missing, benchbro creates it automatically.
If new cases/benchmarks are introduced later, missing entries are merged into baseline.
Pass --new-baseline to replace the entire baseline with the current run.
Pass --ci to use .benchbro/baseline.ci.json for baseline read/write/compare.
Pass --no-compare to skip comparison while still backfilling missing benchmark entries in baseline.
By default, regular runs do not write artifacts.
Use explicit output flags (--output-json, --output-csv, --output-md) when needed.
The baseline is always written to:
.benchbro/baseline.local.json(default local mode).benchbro/baseline.ci.jsonwhen using--ci
Recommended:
- ignore
.benchbro/for machine-local benchmarking artifacts. - commit
.benchbro/baseline.ci.jsonfor CI comparisons.
Recommended .gitignore
# Benchbro local artifacts
.benchbro/*
!.benchbro/baseline.ci.json
If requested, markdown output can also be written with --output-md.
JSON artifacts include environment metadata for reproducibility (Python/runtime/platform/CPU fields) both at run level and on each benchmark entry.
CLI basics
Run selected cases/tags and write outputs:
uv run benchbro my_benchmarks.py \
--case hashing \
--tag fast \
--output-json artifacts/current.json \
--output-csv artifacts/current.csv \
--output-md artifacts/current.md
Compare against baseline:
uv run benchbro my_benchmarks.py
Render time benchmark histograms in terminal output:
uv run benchbro my_benchmarks.py --histogram
Skip comparison for a run while still maintaining baseline structure:
uv run benchbro my_benchmarks.py --no-compare
Regression status uses each benchmark's effective thresholds (benchmark override -> case threshold -> defaults):
- warning default:
50% - error threshold default:
100%
The comparison table shows warning and threshold values for each row.
Histograms are terminal-only in v1 and are shown for time benchmarks.
End-to-end example
For a complete runnable workflow (baseline + candidate comparison), use:
examples/README.mdmake examples
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file benchbro-0.4.1.tar.gz.
File metadata
- Download URL: benchbro-0.4.1.tar.gz
- Upload date:
- Size: 18.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ad66161a57480b29a6d86fc74a5431ee3ebbe79fd6234dcf9bfbef2275729bd
|
|
| MD5 |
46e4a39d51e979de6913b5cd8d285635
|
|
| BLAKE2b-256 |
c09749df3897c74fd8e324587c23cc0c37095ebf0663d799ebc86cef0d4e27a8
|
File details
Details for the file benchbro-0.4.1-py3-none-any.whl.
File metadata
- Download URL: benchbro-0.4.1-py3-none-any.whl
- Upload date:
- Size: 13.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
689c21572386fbce3579a9d32a322af92be0cd8fe335fab289a0fe84f266ea05
|
|
| MD5 |
ec62b2923dc704098819e78d90080367
|
|
| BLAKE2b-256 |
d86fb52c55c7d9613f6061070c861451da03b5bb8219abea631609f227b65783
|