Skip to content

Commit ef5db51

Browse files
committed
add benchmarks
1 parent b3e9aed commit ef5db51

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ test = [
8383
'numpydoc',
8484
"hypothesis",
8585
"pytest-xdist",
86+
"pytest-benchmark",
87+
"pytest-codspeed",
8688
"packaging",
8789
"tomlkit",
8890
"uv",

tests/benchmarks/__init__.py

Whitespace-only changes.

tests/benchmarks/test_e2e.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
"""
2+
Test the basic end-to-end read/write performance of Zarr
3+
"""
4+
5+
from __future__ import annotations
6+
7+
from dataclasses import dataclass
8+
from typing import TYPE_CHECKING
9+
10+
if TYPE_CHECKING:
11+
from pytest_benchmark.fixture import BenchmarkFixture
12+
13+
from zarr.abc.store import Store
14+
from zarr.core.common import NamedConfig
15+
from operator import getitem, setitem
16+
from typing import Any, Literal
17+
18+
import pytest
19+
20+
from zarr import create_array
21+
22+
CompressorName = Literal["gzip"] | None
23+
24+
compressors: dict[CompressorName, NamedConfig[Any, Any] | None] = {
25+
None: None,
26+
"gzip": {"name": "gzip", "configuration": {"level": 1}},
27+
}
28+
29+
30+
@dataclass(kw_only=True, frozen=True)
31+
class Layout:
32+
shape: tuple[int, ...]
33+
chunks: tuple[int, ...]
34+
shards: tuple[int, ...] | None
35+
36+
37+
layouts: tuple[Layout, ...] = (
38+
Layout(shape=(16,), chunks=(1,), shards=None),
39+
Layout(shape=(16,), chunks=(16,), shards=None),
40+
Layout(shape=(16,), chunks=(1,), shards=(1,)),
41+
Layout(shape=(16,), chunks=(1,), shards=(16,)),
42+
Layout(shape=(16,) * 2, chunks=(1,) * 2, shards=None),
43+
Layout(shape=(16,) * 2, chunks=(16,) * 2, shards=None),
44+
Layout(shape=(16,) * 2, chunks=(1,) * 2, shards=(1,) * 2),
45+
Layout(shape=(16,) * 2, chunks=(1,) * 2, shards=(16,) * 2),
46+
)
47+
48+
49+
@pytest.mark.parametrize("compression_name", [None, "gzip"])
50+
@pytest.mark.parametrize("layout", layouts)
51+
@pytest.mark.parametrize("store", ["memory", "local", "zip"], indirect=["store"])
52+
def test_write_array(
53+
store: Store, layout: Layout, compression_name: CompressorName, benchmark: BenchmarkFixture
54+
) -> None:
55+
"""
56+
Test the time required to fill an array with a single value
57+
"""
58+
arr = create_array(
59+
store,
60+
dtype="uint8",
61+
shape=layout.shape,
62+
chunks=layout.chunks,
63+
shards=layout.shards,
64+
compressors=compressors[compression_name],
65+
fill_value=0,
66+
)
67+
68+
benchmark.pedantic(setitem, args=(arr, Ellipsis, 1), rounds=16)
69+
70+
71+
@pytest.mark.parametrize("compression_name", [None, "gzip"])
72+
@pytest.mark.parametrize("layout", layouts)
73+
@pytest.mark.parametrize("store", ["memory", "local", "zip"], indirect=["store"])
74+
def test_read_array(
75+
store: Store, layout: Layout, compression_name: CompressorName, benchmark: BenchmarkFixture
76+
) -> None:
77+
"""
78+
Test the time required to fill an array with a single value
79+
"""
80+
arr = create_array(
81+
store,
82+
dtype="uint8",
83+
shape=layout.shape,
84+
chunks=layout.chunks,
85+
shards=layout.shards,
86+
compressors=compressors[compression_name],
87+
fill_value=0,
88+
)
89+
arr[:] = 1
90+
benchmark.pedantic(getitem, args=(arr, Ellipsis), rounds=16)

0 commit comments

Comments
 (0)