Skip to main content

The memory companion to pytest-benchmark: a memray peak-memory pass on the same test, plus dims-aware plots and cross-version sweeps.

Project description

pytest-benchmem

PyPI Python versions CI Docs Ruff License: MIT

The memory companion to pytest-benchmark. It times your code; pytest-benchmem adds a memray peak-memory pass to the same test, in the same run โ€” one node id, one JSON file, both metrics. memray-precision (it sees numpy/C allocations), not coarse RSS sampling.

๐Ÿ“– Full documentation

Quickstart

A drop-in for an existing pytest-benchmark suite โ€” add --benchmark-memory, no test changes:

pytest --benchmark-only --benchmark-memory --benchmark-columns=min,mean,median
  Name (time in us)                    Min                  Mean                Median   โ”‚   peakยทmin (KiB)   peakยทmean   peakยทmax
 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  test_sort[10000]           30.2079 (1.0)         37.3511 (1.0)         38.6250 (1.0)   โ”‚            78.12       78.12      78.12
  test_sort[100000]        299.2500 (9.91)      404.0027 (10.82)      408.5415 (10.58)   โ”‚           781.25      781.25     781.25
  test_sort[1000000]   3,667.6250 (121.41)   4,427.5485 (118.54)   4,361.7500 (112.93)   โ”‚         7,812.50    7,812.50   7,812.50

Your pytest-benchmark timing table, untouched, with the memory pass folded in right of the โ”‚ โ€” a separate, untimed memray pass (peak spreads into min/mean/max; allocated / allocations are opt-in). A fourth metric, rss โ€” the whole-process physical peak the OOM killer watches โ€” is opt-in per test via @pytest.mark.benchmem(isolate=True). Already use benchmark.pedantic(setup=โ€ฆ) to rebuild state for timing? That same setup is reused โ€” untracked โ€” before each memory sample, so stateful benchmarks stay accurate with no extra changes.

Compare, gate, plot

benchmem compare โ€” a per-benchmark table (time โ”‚ peak across every stat, each cell a relative (ร—) multiplier vs the best run), or --fail-on to fail CI on a regression:

test_build[n=5000]
             time (s)     time (s)      time (s)      time (s)      time (s)         peak (MiB)     peak (MiB)     peak (MiB)     peak (MiB)     peak (KiB)
 name             min          max          mean        median        stddev   โ”‚            min            max           mean         median         stddev
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
 (base)       2 (1.0)    2.3 (1.0)    2.12 (1.0)    2.08 (1.0)    0.09 (1.0)   โ”‚    60.00 (1.0)    60.50 (1.0)    60.23 (1.0)    60.20 (1.0)    210.41 (1.0)
 (head)   2.05 (1.02)   2.4 (1.04)   2.18 (1.03)   2.12 (1.02)   0.11 (1.22)   โ”‚   72.00 (1.20)   73.20 (1.21)   72.53 (1.20)   72.40 (1.20)   510.86 (2.43)

Gate inline in the run too (--benchmark-memory-compare-fail), and --benchmark-memory-profile DIR keeps the memray .bin of each offender so benchmem flamegraph shows where it grew.

benchmem plot / sweep โ€” dims-aware plotly views (scaling vs input size, A/B scatter, version sweeps) and cross-version runs from one command:

benchmem plot run.json --columns peak
benchmem sweep mypkg 1.2.0 1.3.0 main --suite bench/

Why memray, and where it sits

memray tracks the allocator directly, so it catches the numpy/C-allocation detail that RSS sampling (ASV's peakmem) misses and folds out interpreter baseline. pytest-benchmem rides pytest-benchmark for timing and reads/writes its JSON โ€” it doesn't reimplement timing, a CI dashboard (CodSpeed), or cross-commit history (ASV).

vs pytest-memray โ€” complements, not rivals; both wrap memray, pointed opposite ways. pytest-memray is a guardrail (limit_memory / leak detection over the whole test); pytest-benchmem is a benchmark โ€” only the benchmarked action, alongside timing, compared, swept, and plotted across inputs and versions.

Install

uv add pytest-benchmem            # the fixture + flag + memray engine
uv add "pytest-benchmem[plot]"    # + the plot/compare/sweep CLI (pandas, plotly, typer)

memray is Linux/macOS only; Windows installs cleanly with timing-only (the memory pass raises a clear error there).

Status

Early โ€” extracted from the linopy benchmark suite. API may move before 1.0; see the changelog.

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

pytest_benchmem-0.4.6.tar.gz (250.7 kB view details)

Uploaded Source

Built Distribution

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

pytest_benchmem-0.4.6-py3-none-any.whl (70.0 kB view details)

Uploaded Python 3

File details

Details for the file pytest_benchmem-0.4.6.tar.gz.

File metadata

  • Download URL: pytest_benchmem-0.4.6.tar.gz
  • Upload date:
  • Size: 250.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pytest_benchmem-0.4.6.tar.gz
Algorithm Hash digest
SHA256 0de1be9a025807df615828814033b4f5034c7343ba29b3da10b801ae3c02e363
MD5 5bfa92ac6a6e9ba78db858759e35f4fa
BLAKE2b-256 83e55d4761c9f9410629489386f5dbae8c7ffe8a792c72842b66242d498d3261

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_benchmem-0.4.6.tar.gz:

Publisher: release.yaml on fluxopt/pytest-benchmem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pytest_benchmem-0.4.6-py3-none-any.whl.

File metadata

  • Download URL: pytest_benchmem-0.4.6-py3-none-any.whl
  • Upload date:
  • Size: 70.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pytest_benchmem-0.4.6-py3-none-any.whl
Algorithm Hash digest
SHA256 3b3d954534ea21d8860fe1c54b15ea7c6e0d8d54ae1a24020028ec9d3bff7d5b
MD5 ad270d3b88e195a41f6f702702ecada9
BLAKE2b-256 0065eff9be5b8533aa0d7961597bd0fc935724acdf7443b476894208b57eccff

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_benchmem-0.4.6-py3-none-any.whl:

Publisher: release.yaml on fluxopt/pytest-benchmem

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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