Skip to content

perf(writing): checksum structures from their encoded bytes - #193

Open
Blackclaws wants to merge 2 commits into
Apollo3zehn:devfrom
Blackclaws:perf/checksum-in-memory
Open

Blackclaws wants to merge 2 commits into
Apollo3zehn:devfrom
Blackclaws:perf/checksum-in-memory

Conversation

@Blackclaws

Copy link
Copy Markdown
Contributor

Every checksummed structure - object headers, the superblock, the fixed array index header and data block - was written to the stream, read back, checksummed from what was read, and the checksum written after it. That costs an async read per structure, and on a buffered FileStream each read-back flushes the write buffer first.

Each structure is now encoded into a buffer (H5SpanWriteDriver, pooled for object headers), checksummed there, and written in one piece. A chunked dataset's object header, which is patched once its index is known, is kept as an encoded copy and patched in memory instead of being read back from the file. Only chunked datasets keep that copy, since they are the only ones whose header changes after it is written.

The writer no longer reads from its destination at all. This PR does not lift the CanRead requirement on the stream - that would be a behaviour change of its own - but it is what makes lifting it possible; the TODO next to the check now says so.

Numbers

300,000 datasets of 6 doubles each, declared through BeginWrite and then written one by one; median of 3 runs, dev against this branch:

                      BeginWrite      Dispose       allocated         peak RSS
contiguous            3.27 -> 1.96 s  0.01 -> 0.01  1531 -> 1295 MB   316 -> 302 MB
chunked, deflate      4.02 -> 2.90 s  2.28 -> 1.67  2274 -> 2036 MB   584 -> 625 MB

The chunked case keeps about 40 MB more resident: the encoded header copies of 300,000 chunked datasets, which replace reading each header back at Dispose.

Tests

WriteWithoutReadingTests writes through a stream that throws on any read - deferred contiguous data, a single filtered chunk, several filtered chunks (fixed array index), variable-length strings and attributes - and checks the result with h5dump. To make that check able to fail, TestUtils gains RunH5Dump, which reports the exit code and both streams unmodified: DumpH5File strips h5dump's error stack so that the fixture comparisons do not depend on the installed version, which also strips every trace of a rejected file. A deliberately corrupted checksum fails all four tests.

🤖 Generated with Claude Code

Blackclaws and others added 2 commits October 23, 2026 12:59
Each header was written to the file and read back to compute its checksum: an
async read per object header, flushing the stream's write buffer every time.
It is now encoded into a pooled buffer, checksummed there and written once.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ading back

The superblock, the fixed-array index header and data block were written, read
back and checksummed from what was read. A chunked dataset's object header was
patched in the file and its checksum recomputed the same way. All of them now
encode into memory and checksum there; a chunked dataset keeps a copy of its
header to patch.

Writing no longer reads from its destination at all, which a forward-only
upload holding only the part it is filling needs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant