diff --git a/changes/3368.misc.rst b/changes/3368.misc.rst new file mode 100644 index 0000000000..92c90cff33 --- /dev/null +++ b/changes/3368.misc.rst @@ -0,0 +1,2 @@ +Improved performance of reading arrays by not unnecessarily using +the fill value. diff --git a/src/zarr/abc/codec.py b/src/zarr/abc/codec.py index 50c3a55eab..fd2773ca0a 100644 --- a/src/zarr/abc/codec.py +++ b/src/zarr/abc/codec.py @@ -427,6 +427,11 @@ async def read( The second slice selection determines where in the output array the chunk data will be written. The ByteGetter is used to fetch the necessary bytes. The chunk spec contains information about the construction of an array from the bytes. + + If the Store returns ``None`` for a chunk, then the chunk was not + written and the implementation must set the values of that chunk (or + ``out``) to the fill value for the array. + out : NDBuffer """ ... diff --git a/src/zarr/codecs/sharding.py b/src/zarr/codecs/sharding.py index 2b9b2259d8..58d34f62e7 100644 --- a/src/zarr/codecs/sharding.py +++ b/src/zarr/codecs/sharding.py @@ -451,11 +451,10 @@ async def _decode_single( ) # setup output array - out = chunk_spec.prototype.nd_buffer.create( + out = chunk_spec.prototype.nd_buffer.empty( shape=shard_shape, dtype=shard_spec.dtype.to_native_dtype(), order=shard_spec.order, - fill_value=0, ) shard_dict = await _ShardReader.from_bytes(shard_bytes, self, chunks_per_shard) @@ -498,11 +497,10 @@ async def _decode_partial_single( ) # setup output array - out = shard_spec.prototype.nd_buffer.create( + out = shard_spec.prototype.nd_buffer.empty( shape=indexer.shape, dtype=shard_spec.dtype.to_native_dtype(), order=shard_spec.order, - fill_value=0, ) indexed_chunks = list(indexer) diff --git a/src/zarr/core/array.py b/src/zarr/core/array.py index 819379e12f..51e638edd8 100644 --- a/src/zarr/core/array.py +++ b/src/zarr/core/array.py @@ -1349,11 +1349,10 @@ async def _get_selection( f"shape of out argument doesn't match. Expected {indexer.shape}, got {out.shape}" ) else: - out_buffer = prototype.nd_buffer.create( + out_buffer = prototype.nd_buffer.empty( shape=indexer.shape, dtype=out_dtype, order=self.order, - fill_value=self.metadata.fill_value, ) if product(indexer.shape) > 0: # need to use the order from the metadata for v2