@@ -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