perf: reduce snapshot round memory usage#1049
Merged
Merged
Conversation
Formatting-only changes split out of the snapshot-memory work. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Keep snapshot-backed state lazy during JSON and export, bound the decompressed SSTable block cache by bytes, and add a narrow fast path for independent scalar-root imports that is validated against the decoded batch before it is applied. Add a memory regression bench plus checksum and round-trip coverage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
WASM Size Report
|
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.
Summary
Reduces peak memory across the large-document round
snapshot import → toJSON → remote update import → local updates → local update export → full snapshot exportwhile preserving lazy state and making cold full-snapshot export substantially cheaper.
What changed
1 << 20entry limit could retain nearly every decompressed block touched by a large document. The cache is now byte-weighted and capped at 4 MiB of decompressed data per table.toJSON. Ephemeral reads no longer create a second temporary wrapper for each decoded lazy container.Snapshot::encoded_lenreserves the final envelope once, avoiding geometricVecgrowth while assembling the result.Benchmark results
Measured with the 11,387,982-byte (10.86 MiB)
.procloudfixture using release WASM builds. Timing values are medians of three adjacent, interleaved runs.main(68587bc5)3b64511b)3ea96a86)mainThe B4 harness's cached snapshot export also improved from 151.04 µs on
mainto 106.61 µs on this PR (about 29% faster).Memory comparison against
mainThe committed memory bench performs 32 local commits with 4 KiB text payloads, exports the resulting local update, then exports and semantically round-trips a complete snapshot. Both revisions were measured with the same script, fixture, parameters, and fresh worker processes.
mainWASM peakmaincontrolled totalControlled totalincludes the input snapshot/update buffers, WASM linear-memory high-water, returned update and snapshot buffers, retainedtoJSONheap growth, and retained binary backing stores.The phase samples show where the WASM reduction comes from:
maintoJSONObserved process max RSS also fell from 256.34 to 181.13 MiB in the causal scenario (−29.3%), and from 404.38 to 180.42 MiB in the independent scenario (−55.4%). RSS is not the gate because it also includes V8, code pages, and allocator behavior.
Validation
cargo test -p loro-internal --lib: 318 passed, 4 ignored.mainand this PR; semantic version comparison passes, so this is not introduced here.Reproduction
Behavior and review notes
maineven though its snapshot phase is 41.5% faster; the table keeps that remaining non-export overhead visible.loro-crdtbehavior changes, andcontext/internal-encoding.mdpluscontext/mergeable-containers.mddocument the maintained invariants.