mirror of
https://github.com/zed-industries/zed.git
synced 2026-07-09 16:00:35 +00:00
## Context `apply_remote_edit` and `apply_local_edit` rebuild the fragment `SumTree` through `FragmentBuilder`. Since #51941, the builder collapsed the entire tree into a flat `Vec<Fragment>` (cloning every fragment) and rebuilt a fresh tree from scratch on every call. The new tree shared no nodes with the previous one, so each edit cost O(N) in the *total* number of fragments: clone all fragments, allocate an entirely new tree, and then free the whole previous tree on assignment — the last part showing up as a large amount of time spent dropping `SumTree`s. That batching was a deliberate win for the bulk `replace_all` path (#51941, one `edit()` carrying millions of ranges), but it penalizes every other caller — most notably `apply_remote_edit`, which runs once per op in a loop in `apply_ops` and so rebuilt the whole tree per remote operation. ## This change Make `FragmentBuilder` chunk-based. Appended slices are kept as intact `SumTree` subtrees, so they keep sharing nodes with the previous tree; only individually pushed fragments are batched into `Vec`s. `to_sum_tree` appends the shared subtrees (touching just the right spine) and builds the loose runs in one pass, parallelizing the large ones. Net effect: - Small edits on large/heavily-fragmented buffers (the `apply_remote_edit` collaborative path) go back to O(edited + log N) with a cheap drop, instead of O(total fragments). - The bulk `replace_all` path keeps its batched build and is not regressed. ## Benchmarks Using the file from #38927 (619 MB CSV, 10,325,246 matches of `"` → `""`), `release-fast`: | Case | flatten (#51941) | this PR | |---|---|---| | `replace_all` (all matches) | 50.70 s | 45.16 s | | replace 1 match (`--single`) | 16.0 ms | 16.0 ms | `replace_all` is ~11% faster and not regressed. The single-match-on-a-freshly-loaded-file case is unchanged, because a fresh `Buffer::local` is barely fragmented, so even the from-scratch rebuild is cheap there; the structural-sharing win is on heavily-fragmented buffers receiving small edits. The `--single` flag added to `editor_benchmarks` makes the latter case measurable. Release Notes: - Improved the performance of applying edits to large buffers --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| LICENSE-GPL | ||