Repository navigation
Cut evaluation plugin overhead and debounce diagnostics - #166
Open
jdesrosiers wants to merge 7 commits into
Open
jdesrosiers wants to merge 7 commits into
jdesrosiers wants to merge 7 commits into
Conversation
DeprecatedDiagnosticsProvider gets the location and value annotations of every node in the document, and most of that time was the overhead of the Pact pipeline that filtered them. A plain loop took the walk over a 150KB GitHub workflow from about 18ms to 2ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The object keywords looked at every incomplete location in the document each time they were evaluated, and every array has one. Incomplete locations are now grouped by their parent's pointer so a keyword only looks at the ones in the object it applies to. Validating a 150KB GitHub workflow went from about 103ms to 84ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
getPointerForNode searches each array for the node's index, so getting the pointer of every string in a document with large arrays was quadratic. walkNodes already builds the pointers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SubschemaTracker kept its state in WeakMaps keyed by context, and setting a WeakMap entry for every keyword was a large part of the plugin's time. The state is now a property of the context under a symbol that's unique to the tracker, so trackers still don't share state. Validating a 150KB GitHub workflow and getting its annotations went from about 57ms to 46ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every change to a document validated it against its schema and sent diagnostics, even while someone was typing faster than the results could be read. Diagnostics for an edit are now sent once the document hasn't changed for 500ms, like VS Code's JSON language server. Unlike VS Code, a document is validated without waiting when it's opened. A change or close cancels a send that's waiting as well as one that's in progress. The delay is an option of buildServer so tests don't have to wait for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The completions of a oneOf were combined with a Pact pipeline for every location under it, and its overhead was a large part of evaluating schemas that use oneOf a lot. The sets are now grouped by location in one pass. Validating a 150KB GitHub workflow went from about 209ms to 163ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Annotations from a conditional subschema were marked as value annotations by copying the subschema's whole record, which has an entry for every location under it, for every anyOf and oneOf alternative. They're now marked while they're appended. Validating a 150KB GitHub workflow went from about 163ms to 144ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
The language server's evaluation plugin adds a lot to every validation. With a 150KB GitHub workflow, it added about 260ms on top of hyperjump's own ~50ms. These changes cut the plugin's own overhead from about 260ms to about 90ms and stop sending diagnostics while someone is typing.
oneOf. Now one pass groups the sets by location.SubschemaTrackerset a WeakMap entry for every keyword. Its state is now a property under a symbol that's unique to the tracker, so trackers still don't share state. This relies on hyperjump creating a fresh context for each keyword, which the WeakMap version also relied on.walkNodesbuilds for document colors.getPointerForNodesearches arrays for the node's index, so colors were quadratic in array size.buildServeroption so tests don't wait for it.Measured with a generated 154KB GitHub workflow against the SchemaStore schema (medians):
Most of what's left is copying completions and annotations up through each schema, which keeps the plugin simple. Recording a tree during evaluation and flattening it when requested took validation to ~200 ms before the last two improvements, but it was left out because it makes the plugin harder to follow. The JSE output plugin is a large part of the remaining time. It computes
Instance.urithree times per keyword, and computing it once saves about 20 ms. That fix belongs in@hyperjump/json-schema-errors.Testing
The debounce has new tests for opening a document, changes in quick succession, and closing before the delay is over. The other changes aren't intended to change behavior. All 540 existing tests pass.
🤖 Generated with Claude Code