Skip to main content

PyBench — precise microbenchmarks for Python

CI PyPI Python Versions License: MIT Downloads

Measure small, focused snippets with minimal boilerplate, auto-discovery, smart calibration, and a clean CLI (pybench).

Run benchmarks with one command:

pybench run examples/ [-k keyword] [-P key=value ...]

✨ Highlights

  • Simple API: use the @bench(...) decorator or suites with Bench + BenchContext.start()/end() to isolate the hot path.
  • Auto-discovery: pybench run <dir> expands to **/*bench.py.
  • Powerful parameterization: generate Cartesian products with params={...} or define per-case args/kwargs.
  • On-the-fly overrides: -P key=value adjusts n, repeat, warmup, group, or custom params without editing code.
  • Solid timing model: monotonic clock, warmup, GC control, and context fast-paths.
  • Smart calibration: per-variant iteration tuning to hit a target budget.
  • Rich reports: aligned tables with percentiles, iter/s, min…max, baseline markers, and speedups vs. base.
  • HTML charts: export benchmarks as self-contained Chart.js dashboards with --export chart.
  • History tooling: runs auto-save to .pybenchx/; list, inspect stats, clean, or compare with --vs {name,last}.

🚀 Quickstart

📦 Install

  • pip
    pip install pybenchx
    
  • uv
    uv pip install pybenchx
    

🧪 Example benchmark

See examples/strings_bench.py for both styles:

from pybench import bench, Bench, BenchContext

@bench(name="join", n=1000, repeat=10)
def join(sep: str = ","):
    sep.join(str(i) for i in range(100))

suite = Bench("strings")

@suite.bench(name="join-baseline", baseline=True)
def join_baseline(b: BenchContext):
    s = ",".join(str(i) for i in range(50))
    b.start(); _ = ",".join([s] * 5); b.end()

🏎️ Running

  • Run all examples
    pybench run examples/
    
  • Filter by name
    pybench run examples/ -k join
    
  • Override params at runtime
    pybench run examples/ -P repeat=5 -P n=10000
    

🎛️ Key CLI options

  • Disable color
    pybench run examples/ --no-color
    
  • Sorting
    pybench run examples/ --sort time --desc
    
  • Time budget per variant (calibration)
    pybench run examples/ --budget 300ms     # total per variant; split across repeats
    pybench run examples/ --max-n 1000000    # cap calibrated n
    
  • Profiles
    pybench run examples/ --profile thorough  # ~1s budget, repeat=30
    pybench run examples/ --profile smoke     # no calibration, repeat=3 (default)
    
  • Save / Compare / Export
    pybench run examples/ --save latest
    pybench run examples/ --save-baseline main
    pybench run examples/ --compare main --fail-on mean:7%,p99:12%
    pybench run examples/ --export chart        # HTML dashboard (Chart.js)
    pybench run examples/ --export json         # JSON next to auto-saved run
    

🗂️ Manage history & baselines

  • List everything under .pybenchx/
    pybench list
    pybench list --baselines
    
  • Storage stats & cleanup
    pybench stats
    pybench clean --keep 50
    
  • Compare quickly
    pybench run examples/ --vs main        # named baseline
    pybench run examples/ --vs last        # last auto-saved run
    

📊 Output

Header includes CPU, Python, perf_counter clock info, total time, and profile. Table shows speed vs baseline with percent:

(pybench) $ pybench run examples/
cpu: x86_64
runtime: python 3.13.5 (x86_64-linux) | perf_counter: res=1.0e-09s, mono=True
time: 23.378s | profile: smoke, budget=-, max-n=1000000, sequential
benchmark                          time (avg)       iter/s              (min … max)          p75          p99         p995      vs base
join                                 13.06 µs       76.6 K      13.00 µs … 13.21 µs     13.08 µs     13.20 µs     13.21 µs            -
join_param[n=100,sep='-']            13.17 µs       75.9 K      12.79 µs … 13.72 µs     13.37 µs     13.70 µs     13.71 µs            -
join_param[n=100,sep=':']            13.06 µs       76.6 K      12.85 µs … 13.23 µs     13.14 µs     13.23 µs     13.23 µs            -
join_param[n=1000,sep='-']          131.75 µs        7.6 K    129.32 µs … 134.82 µs    132.23 µs    134.70 µs    134.76 µs            -
join_param[n=1000,sep=':']          135.62 µs        7.4 K    131.17 µs … 147.50 µs    136.68 µs    146.92 µs    147.21 µs            -
group: strings                                                                                                                  
join-baseline  ★                    376.07 ns        2.7 M    371.95 ns … 384.09 ns    378.96 ns    383.66 ns    383.87 ns     baseline
join-basic                          377.90 ns        2.6 M    365.89 ns … 382.65 ns    381.15 ns    382.55 ns    382.60 ns       ≈ same
concat                               10.62 µs       94.1 K      10.54 µs … 10.71 µs     10.65 µs     10.70 µs     10.71 µs 28.25× slower

💡 Tips

  • Use BenchContext.start()/end() para isolar a seção crítica e evitar ruído de setup.
  • Prefira --profile smoke durante o desenvolvimento; troque para --profile thorough antes de publicar números.
  • Para logs, use --no-color.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pybenchx-1.2.0.tar.gz (128.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pybenchx-1.2.0-py3-none-any.whl (36.5 kB view details)

Uploaded Python 3

File details

Details for the file pybenchx-1.2.0.tar.gz.

File metadata

  • Download URL: pybenchx-1.2.0.tar.gz
  • Upload date:
  • Size: 128.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.2

File hashes

Hashes for pybenchx-1.2.0.tar.gz
Algorithm Hash digest
SHA256 4a1d1d6193fd7cc311cc6d904cb97e5ca47e55b698e65da471e430d18c6ffacc
MD5 195d1732d4e8d013bc8792133f775b53
BLAKE2b-256 355ec656ac9d91731619457c666bc51f07e590894448027226ab11175a7ad9d6

See more details on using hashes here.

File details

Details for the file pybenchx-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: pybenchx-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 36.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.2

File hashes

Hashes for pybenchx-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 95956b69049e684b16e58225a0da04044e0d06ae91f1c3a2b1a5882b40c63008
MD5 d7562cd6eea319606617e1116a582d20
BLAKE2b-256 af6e427250c5afc92149d21b0a9167f6415820d82728d74f7972f4733d645583

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.0.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page