Skip to content

perf(project): reuse cursor ID strings during stabilization - #3195

Merged
richiemcilroy merged 1 commit into
CapSoftware:mainfrom
vedanth-jadhav:perf/reuse-cursor-shape-strings
Oct 25, 2026
Merged

richiemcilroy merged 1 commit into
CapSoftware:mainfrom
vedanth-jadhav:perf/reuse-cursor-shape-strings

Conversation

@vedanth-jadhav

@vedanth-jadhav vedanth-jadhav commented Oct 25, 2026 •

Copy link
Copy Markdown

Cursor stabilization allocates a new ID String for every rewritten move and every click, even when the existing string has enough capacity. The GPUI editor invokes this after reading retained/live cursor data, and MultipleSegment::cursor_events uses it during project cursor loading.

Use String::clone_from for the two event-ID assignments. This reuses each event's existing string storage. Segment construction, duration/fallback selection, pointer protection, click boundaries, and final-click duration confirmation stay the same. Two production lines change; no public API or cache is introduced.

Release measurements

Baseline 5c1e9d1be, Linux x86_64 container, AMD EPYC 9V74, two-CPU quota, CPU 0 affinity, Rust 1.88.0. Root release profile (opt-level=s, thin LTO, one codegen unit). Five alternating independent processes per version; 25 samples after three warmups. Medians of process medians:

Fixture Before After Time reduction
Single-shape control, 3,600 moves 0.009013 ms 0.008202 ms 9.0%
Long-lived shapes, 36,000 moves 0.148470 ms 0.129361 ms 12.9%
Brief shapes, 36,000 moves 0.184352 ms 0.144754 ms 21.5%
Brief shapes, 216,000 moves 1.732789 ms 1.429030 ms 17.5%
No pointer metadata, 36,000 moves 0.182740 ms 0.140557 ms 23.1%
Growing numeric IDs, 36,000 moves 0.184172 ms 0.169390 ms 8.0%
Legacy word IDs, 36,000 moves 0.185554 ms 0.159735 ms 13.9%

Fixtures use the recorder's current short numeric ID format (next_cursor_id.to_string()), with growing-ID and legacy-name controls. Dense movement is sampled at 60 Hz: 36,000 events represent ten minutes and 216,000 represent one hour of continuous movement. Brief shapes last 250 ms per four-second cycle; long-shape controls last two seconds. Click events are spaced at half-second intervals. These are synthetic component workloads, not average recordings or an end-to-end editor startup/FPS claim.

Cloning inputs, serialization/checksums, and output destruction are outside timing. Every sample is checked, and all baseline/head fingerprints match, including the metadata-free case (its dominant shape is unique). The unchanged one-shape control is small and its timing should not be interpreted as a causal benefit from the rewritten assignments.

A separate System-allocator probe measured 27,013 allocation/reallocation events before versus 6,313 after for 216,000 numeric-ID moves and 7,200 clicks: 20,700 fewer calls. This counter excludes input construction and is separate from the timing binaries. Retained ID-string capacities sum to 223,200 bytes on both versions for this case.

Capacity is intentionally reused rather than shrunk. The growing-ID control retains 122,850 ID-capacity bytes versus 111,600 before; the legacy-name control retains 267,150 versus 260,400. Arbitrarily long old identifiers can likewise retain spare capacity after shortening. No process-RSS or universal retained-memory reduction is claimed.

Correctness and validation

A new normal test compares complete event encodings with independently constructed expected events for equal-length, growing, UTF-8, empty, and long-to-short IDs. It verifies untouched modifiers, click fields, timestamps, NaN coordinate payload bits and negative zero. Existing pointer preference, long-shape preservation, final-click confirmation, and metadata-free fallback tests pass.

  • cargo fmt --all and cargo fmt --all --check
  • cargo check -p cap-project --locked
  • cargo test -p cap-project --locked: 179 library + 4 integration tests passed; 4 existing benchmarks ignored.
  • cargo clippy -p cap-project --all-targets --locked -- -D warnings
  • git diff --check

Reproduction

Use this branch's example on both revisions, save the two binaries, then alternate five runs each:

cargo build -p cap-project --release --locked --example cursor-stabilization-benchmark -j 2
taskset -c 0 target/release/examples/cursor-stabilization-benchmark

The example prints per-sample API timings and complete-event fingerprints. Raw samples and experimental allocator instrumentation remain outside Cap. No native GUI/capture or macOS/Windows run was performed. The allocation reuse and disclosed capacity retention are the only intended behavior differences.

Publication validation: rebased onto ec15b9840; 183 scoped tests passed, plus formatting, check, and strict all-target Clippy. Benchmarks above were recorded before this rebase; the production paths changed by this PR remain as measured.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge.

Summary

Reuses existing cursor_id storage with String::clone_from when updating moves and clicks.

  • Cursor stabilization reuses ID strings for rewritten moves and clicks.

Reviews (1) · Last reviewed commit: "perf(project): reuse cursor ID strings d..." · Reviewed by Greptile

@vercel

vercel Bot commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Someone is attempting to deploy a commit to the Cap Software Inc Team on Vercel.

A member of the Team first needs to authorize it.

vedanth-jadhav commented Oct 25, 2026 •

Copy link
Copy Markdown
Author

CI triage for this head:

  • Intel macOS GPUI job: GitHub reports “The hosted runner lost communication with the server.”
  • macOS real-capture job: fails in “Blacksmith capture permissions and audio device” setup, before the recording tests run. The verification aggregate consequently fails too.
  • The macOS sync log, now retrieved through the GitHub connector, identifies audio::tests::a_stale_render_is_released_once_the_next_render_finishes: the supposedly cached paused render is already absent.

I reproduced a cache-retention/publication race on main and submitted the focused fix in #3219. Its deterministic regression fails on baseline and passes with the fix; all 215 editor library tests pass locally. It registers retention before a fast worker can finish, while preserving publication after successful worker creation.

Linux/Windows Rust tests and the Rust Clippy gates passed for this PR. Rerunning the infrastructure jobs still requires upstream Actions permission: both the CLI and GitHub connector reject the targeted rerun with HTTP 403, “Resource not accessible by integration.”

@richiemcilroy
richiemcilroy merged commit a4928f6 into CapSoftware:main Oct 25, 2026
64 of 70 checks passed
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.

2 participants