diff --git a/newsfragments/54.misc.rst b/newsfragments/54.misc.rst new file mode 100644 index 0000000..5c87080 --- /dev/null +++ b/newsfragments/54.misc.rst @@ -0,0 +1 @@ +Add optional ``pytest-benchmark`` suite for ``sum`` / ``encode`` / ``decode`` (excluded from default CI via the ``benchmark`` marker). diff --git a/pyproject.toml b/pyproject.toml index c27f9d8..5e14f4f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,7 @@ dev = [ "pre-commit", "pycryptodome>=3.0,<4.0", "pytest", + "pytest-benchmark", "pytest-cov", "pytest-runner", "ruff", @@ -65,6 +66,10 @@ include = ["multihash*"] [tool.pytest.ini_options] testpaths = ["tests"] python_classes = "*TestCase" +addopts = "-m 'not benchmark'" +markers = [ + "benchmark: performance benchmarks (excluded from default test runs)", +] [tool.towncrier] # Read https://github.com/multiformats/py-multihash/blob/master/newsfragments/README.md for instructions diff --git a/tests/test_benchmarks.py b/tests/test_benchmarks.py new file mode 100644 index 0000000..67458d4 --- /dev/null +++ b/tests/test_benchmarks.py @@ -0,0 +1,43 @@ +"""Benchmark tests for core multihash operations. + +Excluded from default ``make test`` / tox core runs via the ``benchmark`` marker. +Run explicitly with:: + + pytest -m benchmark tests/test_benchmarks.py +""" + +import pytest + +from multihash import Func, decode, sum + +BENCH_DATA = b"benchmark test data for multihash operations" * 100 + +pytestmark = pytest.mark.benchmark + + +def test_bench_sum_sha256(benchmark): + benchmark(sum, BENCH_DATA, Func.sha2_256) + + +def test_bench_sum_sha512(benchmark): + benchmark(sum, BENCH_DATA, Func.sha2_512) + + +def test_bench_sum_blake3(benchmark): + benchmark(sum, BENCH_DATA, Func.blake3) + + +@pytest.mark.parametrize("bits", [8, 128, 256, 384, 512]) +def test_bench_sum_blake2b(benchmark, bits): + func = getattr(Func, f"blake2b_{bits}") + benchmark(sum, BENCH_DATA, func) + + +def test_bench_encode(benchmark): + mh = sum(BENCH_DATA, Func.sha2_256) + benchmark(mh.encode) + + +def test_bench_decode(benchmark): + encoded = sum(BENCH_DATA, Func.sha2_256).encode() + benchmark(decode, encoded) diff --git a/uv.lock b/uv.lock index cfd100c..a917855 100644 --- a/uv.lock +++ b/uv.lock @@ -1219,6 +1219,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, ] +[[package]] +name = "py-cpuinfo2" +version = "10.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/97/a8b1ddada14c8280a047c0746f95cb05d94a31b1a331cea22bcdc2b2a82d/py_cpuinfo2-10.1.1.tar.gz", hash = "sha256:7861133863663f16e06eca63b12904ef100b5760415e92372dac0162799a4771", size = 100840, upload-time = "2026-03-25T21:49:40.797Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/0a/ba69d2dde1ae12ef1d389ea5a216384c5ff6ef7a1e7a48d1e9b6686f6790/py_cpuinfo2-10.1.1-py3-none-any.whl", hash = "sha256:adc53396bfb206e6498d078ec2ab407f85799ecd819584ac36a8f80a2d4d762d", size = 23791, upload-time = "2026-03-25T21:49:39.574Z" }, +] + [[package]] name = "py-multihash" version = "3.0.0" @@ -1237,6 +1246,7 @@ dev = [ { name = "pre-commit" }, { name = "pycryptodome" }, { name = "pytest" }, + { name = "pytest-benchmark" }, { name = "pytest-cov" }, { name = "pytest-runner" }, { name = "ruff" }, @@ -1264,6 +1274,7 @@ requires-dist = [ { name = "pycryptodome", marker = "extra == 'dev'", specifier = ">=3.0,<4.0" }, { name = "pycryptodome", marker = "extra == 'keccak'", specifier = ">=3.0,<4.0" }, { name = "pytest", marker = "extra == 'dev'" }, + { name = "pytest-benchmark", marker = "extra == 'dev'" }, { name = "pytest-cov", marker = "extra == 'dev'" }, { name = "pytest-runner", marker = "extra == 'dev'" }, { name = "ruff", marker = "extra == 'dev'" }, @@ -1517,6 +1528,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, ] +[[package]] +name = "pytest-benchmark" +version = "5.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "py-cpuinfo2" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/8f/83a15e40dbc34a580ee56eb56983cae5394c6e94d50cf28fe268e457be25/pytest_benchmark-5.3.0.tar.gz", hash = "sha256:358444d4e89be901ee2b6404fb043ac3d7684002ad7f3563cc153fca6339c965", size = 375410, upload-time = "2026-08-23T17:45:08.891Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/42/7e80f7cfa191e0a766d1de99b4661847415ad5db34f8209d81fd42175b59/pytest_benchmark-5.3.0-py3-none-any.whl", hash = "sha256:920ab1dfcffa718d49aa15ba144c7e357bda59216a0dc308016cc1c7236f719d", size = 48401, upload-time = "2026-08-23T17:45:07.094Z" }, +] + [[package]] name = "pytest-cov" version = "7.0.0"