Skip to content

Commit 1cad983

Browse files
committed
test:Add indexing benchmarks for writing
1 parent c872e2b commit 1cad983

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

tests/benchmarks/test_indexing.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,115 @@ def read_with_cache_clear() -> None:
190190
getitem(data, indexer)
191191

192192
benchmark(read_with_cache_clear)
193+
194+
195+
# Benchmark for morton_order_iter directly (no I/O)
196+
morton_iter_shapes = (
197+
(8, 8, 8), # 512 elements
198+
(16, 16, 16), # 4096 elements
199+
(32, 32, 32), # 32768 elements
200+
)
201+
202+
203+
@pytest.mark.parametrize("shape", morton_iter_shapes, ids=str)
204+
def test_morton_order_iter(
205+
shape: tuple[int, ...],
206+
benchmark: BenchmarkFixture,
207+
) -> None:
208+
"""Benchmark morton_order_iter directly without I/O.
209+
210+
This isolates the Morton order computation to measure the
211+
optimization impact without array read/write overhead.
212+
The cache is cleared before each iteration.
213+
"""
214+
from zarr.core.indexing import _morton_order, morton_order_iter
215+
216+
def compute_morton_order() -> None:
217+
_morton_order.cache_clear()
218+
# Consume the iterator to force computation
219+
list(morton_order_iter(shape))
220+
221+
benchmark(compute_morton_order)
222+
223+
224+
# Benchmark for Morton order in write path
225+
# Morton order is used when encoding shards, so writes should show improvement
226+
@pytest.mark.parametrize("store", ["memory"], indirect=["store"])
227+
@pytest.mark.parametrize("shards", large_morton_shards, ids=str)
228+
def test_sharded_morton_write_full(
229+
store: Store,
230+
shards: tuple[int, ...],
231+
benchmark: BenchmarkFixture,
232+
) -> None:
233+
"""Benchmark writing a full shard with Morton order.
234+
235+
Morton order is used in the write/encode path of the sharding codec.
236+
This benchmark writes to a full shard with cache clearing to measure
237+
the Morton optimization impact on writes.
238+
"""
239+
import numpy as np
240+
241+
from zarr.core.indexing import _morton_order
242+
243+
shape = tuple(s * 2 for s in shards)
244+
chunks = (1,) * 3
245+
246+
data = create_array(
247+
store=store,
248+
shape=shape,
249+
dtype="uint8",
250+
chunks=chunks,
251+
shards=shards,
252+
compressors=None,
253+
filters=None,
254+
fill_value=0,
255+
)
256+
257+
# Pre-create write data
258+
write_data = np.ones(shards, dtype="uint8")
259+
indexer = (slice(shards[0]),) * 3
260+
261+
def write_with_cache_clear() -> None:
262+
_morton_order.cache_clear()
263+
data[indexer] = write_data
264+
265+
benchmark(write_with_cache_clear)
266+
267+
268+
@pytest.mark.parametrize("store", ["memory"], indirect=["store"])
269+
@pytest.mark.parametrize("shards", morton_iter_shapes, ids=str)
270+
def test_sharded_morton_write(
271+
store: Store,
272+
shards: tuple[int, ...],
273+
benchmark: BenchmarkFixture,
274+
) -> None:
275+
"""Benchmark writing to sharded arrays with various shard sizes.
276+
277+
Tests Morton order impact on writes across different shard sizes.
278+
"""
279+
import numpy as np
280+
281+
from zarr.core.indexing import _morton_order
282+
283+
shape = tuple(s * 2 for s in shards)
284+
chunks = (1,) * len(shards)
285+
286+
data = create_array(
287+
store=store,
288+
shape=shape,
289+
dtype="uint8",
290+
chunks=chunks,
291+
shards=shards,
292+
compressors=None,
293+
filters=None,
294+
fill_value=0,
295+
)
296+
297+
write_data = np.ones(shards, dtype="uint8")
298+
indexer = tuple(slice(s) for s in shards)
299+
300+
def write_with_cache_clear() -> None:
301+
_morton_order.cache_clear()
302+
data[indexer] = write_data
303+
304+
benchmark(write_with_cache_clear)

0 commit comments

Comments
 (0)