From b81844a81f2dc3d03891ebefdd4f5d193fb8fbbf Mon Sep 17 00:00:00 2001 From: Claude Subagent Date: Sat, 21 Mar 2026 13:01:18 -0700 Subject: [PATCH] feat: Add parametrized benchmarks for Zarr v2 and v3 formats - Extends existing read/write benchmarks to test both v2 and v3 - Parametrizes on zarr_format, compression, layout, and store type - Skips v2 + sharding combinations (not supported in v2) - Reuses existing test structure per maintainer feedback - Provides performance comparison across Zarr versions Addresses feedback: 'better to reuse existing tests with parametrization' --- changes/3757.feature.md | 6 ++++++ tests/benchmarks/test_e2e.py | 33 ++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 changes/3757.feature.md diff --git a/changes/3757.feature.md b/changes/3757.feature.md new file mode 100644 index 0000000000..55bc6cb16d --- /dev/null +++ b/changes/3757.feature.md @@ -0,0 +1,6 @@ +Add parametrized benchmark tests for both Zarr v2 and v3 formats + +- Extends existing read/write benchmarks to test both v2 and v3 +- Parametrizes on zarr_format, compression, layout, and store type +- Skips v2 + sharding combinations (not supported in v2) +- Provides performance comparison between Zarr versions diff --git a/tests/benchmarks/test_e2e.py b/tests/benchmarks/test_e2e.py index 65d0e65ac9..39ff230c5f 100644 --- a/tests/benchmarks/test_e2e.py +++ b/tests/benchmarks/test_e2e.py @@ -13,6 +13,7 @@ from zarr.abc.store import Store from zarr.core.common import NamedConfig + from operator import getitem, setitem from typing import Any, Literal @@ -21,13 +22,13 @@ from zarr import create_array CompressorName = Literal["gzip"] | None +ZarrFormat = Literal[2, 3] compressors: dict[CompressorName, NamedConfig[Any, Any] | None] = { None: None, "gzip": {"name": "gzip", "configuration": {"level": 1}}, } - layouts: tuple[Layout, ...] = ( # No shards, just 1000 chunks Layout(shape=(1_000_000,), chunks=(1000,), shards=None), @@ -38,17 +39,28 @@ ) +@pytest.mark.parametrize("zarr_format", [2, 3]) @pytest.mark.parametrize("compression_name", [None, "gzip"]) @pytest.mark.parametrize("layout", layouts, ids=str) @pytest.mark.parametrize("store", ["memory", "local"], indirect=["store"]) def test_write_array( - store: Store, layout: Layout, compression_name: CompressorName, benchmark: BenchmarkFixture + store: Store, + layout: Layout, + compression_name: CompressorName, + zarr_format: ZarrFormat, + benchmark: BenchmarkFixture, ) -> None: """ - Test the time required to fill an array with a single value + Test the time required to fill an array with a single value. + Parametrized to benchmark both Zarr v2 and v3 formats. """ + # Skip v2 tests with sharding (not supported in v2) + if zarr_format == 2 and layout.shards is not None: + pytest.skip("Sharding not supported in Zarr v2") + arr = create_array( store, + zarr_format=zarr_format, dtype="uint8", shape=layout.shape, chunks=layout.chunks, @@ -60,17 +72,28 @@ def test_write_array( benchmark(setitem, arr, Ellipsis, 1) +@pytest.mark.parametrize("zarr_format", [2, 3]) @pytest.mark.parametrize("compression_name", [None, "gzip"]) @pytest.mark.parametrize("layout", layouts, ids=str) @pytest.mark.parametrize("store", ["memory", "local"], indirect=["store"]) def test_read_array( - store: Store, layout: Layout, compression_name: CompressorName, benchmark: BenchmarkFixture + store: Store, + layout: Layout, + compression_name: CompressorName, + zarr_format: ZarrFormat, + benchmark: BenchmarkFixture, ) -> None: """ - Test the time required to fill an array with a single value + Test the time required to read an array. + Parametrized to benchmark both Zarr v2 and v3 formats. """ + # Skip v2 tests with sharding (not supported in v2) + if zarr_format == 2 and layout.shards is not None: + pytest.skip("Sharding not supported in Zarr v2") + arr = create_array( store, + zarr_format=zarr_format, dtype="uint8", shape=layout.shape, chunks=layout.chunks,