Hoist per-chunk config lookups and parallelize deep group traversal#184
Draft
d-v-b wants to merge 7 commits into
Draft
Hoist per-chunk config lookups and parallelize deep group traversal#184d-v-b wants to merge 7 commits into
d-v-b wants to merge 7 commits into
Conversation
…#176) Bumps the actions group with 8 updates in the / directory: | Package | From | To | | --- | --- | --- | | [prefix-dev/setup-pixi](https://github.com/prefix-dev/setup-pixi) | `0.9.5` | `0.9.6` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `6.0.0` | `6.0.1` | | [github/issue-metrics](https://github.com/github/issue-metrics) | `4.2.2` | `4.2.7` | | [j178/prek-action](https://github.com/j178/prek-action) | `2.0.3` | `2.0.4` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `7.0.0` | `7.0.1` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `7.0.0` | `8.0.1` | | [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) | `1.13.0` | `1.14.0` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.3` | `0.5.6` | Updates `prefix-dev/setup-pixi` from 0.9.5 to 0.9.6 - [Release notes](https://github.com/prefix-dev/setup-pixi/releases) - [Commits](prefix-dev/setup-pixi@1b2de7f...5185adf) Updates `codecov/codecov-action` from 6.0.0 to 6.0.1 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](codecov/codecov-action@57e3a13...e79a696) Updates `github/issue-metrics` from 4.2.2 to 4.2.7 - [Release notes](https://github.com/github/issue-metrics/releases) - [Commits](github-community-projects/issue-metrics@c9e9838...1e38d5e) Updates `j178/prek-action` from 2.0.3 to 2.0.4 - [Release notes](https://github.com/j178/prek-action/releases) - [Commits](j178/prek-action@6ad8027...bdca6f1) Updates `actions/upload-artifact` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@v7...043fb46) Updates `actions/download-artifact` from 7.0.0 to 8.0.1 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](actions/download-artifact@v7...3e5f45b) Updates `pypa/gh-action-pypi-publish` from 1.13.0 to 1.14.0 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](pypa/gh-action-pypi-publish@v1.13.0...cef2210) Updates `zizmorcore/zizmor-action` from 0.5.3 to 0.5.6 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](zizmorcore/zizmor-action@b1d7e1f...5f14fd0) --- updated-dependencies: - dependency-name: prefix-dev/setup-pixi dependency-version: 0.9.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: codecov/codecov-action dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: github/issue-metrics dependency-version: 4.2.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: j178/prek-action dependency-version: 2.0.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: pypa/gh-action-pypi-publish dependency-version: 1.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…rsal Hoist `async.concurrency` config lookups to once per read/write/encode/ decode operation via an operation-scoped cache (`async_concurrency_scope` / `get_async_concurrency` in `zarr.core.config`), instead of re-reading Donfig config per chunk and per codec stage on the codec pipeline hot path. Config changes between operations are still honored. Drive recursion into sibling subgroups concurrently in `_iter_members_deep` so sibling subtrees overlap their latency, instead of draining each subgroup iterator sequentially. The shared semaphore still bounds total concurrent `getitem` calls; member ordering remains unspecified (as documented). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Open
59 tasks
db473cd to
fd6189b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses P4–P6 of #181.
Three independent performance findings were investigated. Two are implemented; one was found to be invalid on inspection and is documented below.
1. Hoist repeated
async.concurrencyconfig lookups off the per-chunk codec path (P4)With the default
codec_pipeline.batch_size=1, the read/write/encode/decode paths re-readconfig.get("async.concurrency")once per chunk (inread_batch/write_batch), once per batch inread/write, and once per codec per chunk via_batching_helperand the partial decode/encode mixins. Each lookup walks Donfig's nested config.This adds an operation-scoped cache in
zarr.core.config:async_concurrency_scope()— a context manager that capturesasync.concurrencyonce.get_async_concurrency()— returns the captured value inside a scope, else falls back to a liveconfig.get.BatchedCodecPipeline.read/write/decode/encodenow wrap their bodies in the scope, and all eight per-chunk/per-codec lookups (5 incodec_pipeline.py, 3 inabc/codec.py) read throughget_async_concurrency(). No public signatures changed. Config changes between operations are still honored (each operation re-captures on entry); only mid-operation changes are ignored, which is the intended hoisting behavior. Verified manually.2. Parallelize deep group traversal across sibling subgroups (P5)
_iter_members_deeppreviously drained each subgroup's recursive iterator in sequence (for prefix, subgroup_iter in to_recurse.items(): async for ...), so sibling subtrees did not overlap latency. It now drives sibling iterators concurrently via per-subgroup drain tasks feeding anasyncio.Queue, yielding members as they arrive. The sharedasyncio.Semaphore(already threaded into every recursive call) still bounds total concurrentgetitemoperations. Member ordering remains unspecified, as documented onGroup.members— existing tests already sort before comparing, and the fulltests/test_group.pysuite passes.3. (SKIPPED)
StorePath.__truediv__re-normalizing per chunk (P6)Skipped: the premise does not hold against the current code.
StorePath.__truediv__calls_join_paths([self.path, other]), which is a plain"/".join(filter(...))with no regex, nosplit, and no dot-segment scan. It does not callnormalize_path. The per-chunk join is already a cheap fast path, so there is nothing to optimize here without a risky micro-optimization of_join_pathsfor negligible benefit. No change made.Test results (
uv run)uv run pytest tests/test_codecs/ tests/test_group.py tests/test_store/ -q→ 2000 passed, 207 skipped, 2 xfaileduv run pytest tests/test_indexing.py -q→ 424 passed, 1 skipped, 5 xfaileduv run pytest tests/test_config.py -q→ 37 passeduv run mypy src/zarr/core/config.py src/zarr/core/codec_pipeline.py src/zarr/abc/codec.py src/zarr/core/group.py→ Success: no issues found in 4 source filesNote
No towncrier changelog entry was added — one should be added before this is un-drafted.
🤖 Generated with Claude Code