perf(lsp): O(doc) semantic token encoding + delta + cancellation#26
Merged
Conversation
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.
Slice 2.5 Fase 3. The baseline flagged semanticTokens/full on the large fixture at ~70ms p95 -- the one operation near an ADR-010 budget.
Root cause (the real win): the cost was never token computation (Semantic_tokens.of_blocks is 0.83ms) -- it was the LSP delta-position encoding calling Doc_position.of_offset (O(offset), counts lines from the document start) once per token, i.e. O(n2) over the document. Replaced with a single forward cursor over the sorted tokens (O(doc)). semanticTokens/full [large]: 69.7ms -> 1.77ms p95 (40x).
semanticTokens/full/delta (LSP 3.17): server stores the last (resultId, data) per document and returns a minimal prefix/suffix edit list; falls back to a full result on a stale/unknown previousResultId (spec-allowed). Saves transport + client re-tokenization for future token-consuming clients.
Cancellation: a dedicated reader thread parses incoming messages and records $/cancelRequest ids; the main loop skips a stale request before doing its work and answers RequestCancelled. Processing stays single-threaded (only the main loop touches docs/stores/stdout). With no request now exceeding ~2ms, the pre-process check is sufficient -- no mid-flight interruption needed.
Tests: 5 new protocol checks (full+resultId, delta no-change -> empty edits, delta after edit -> non-empty edits, cancel -> error/no result, no cancel bleed). 112 total green. The existing semantic-token correctness tests cover the new encoding. CI budget gate stays green.
Note: the desktop does not consume server semantic tokens (Lezer first-paint), so delta benefits future IDE clients; the encoding fix + cancellation ship in the bundled binary regardless.