Skip to content

First Validation performance improvements #1729

Open
markwpearce wants to merge 8 commits into
v1from
more_validation_performance_improvements
Open

First Validation performance improvements #1729
markwpearce wants to merge 8 commits into
v1from
more_validation_performance_improvements

Conversation

@markwpearce

@markwpearce markwpearce commented Jun 6, 2026

Copy link
Copy Markdown
Collaborator

In v1, the first run still went through incremental-style dependency analysis (figuring out changed symbols, affected files, and impacted scopes).
In this branch, first validation explicitly assumes everything should be validated, which removes a lot of expensive bookkeeping on cold start.

What is different from v1 for first validation

Before (v1)

  • First validation used changed-symbol and cross-scope dependency flows similar to revalidation.
  • Scope invalidation and file selection were driven by dependency discovery.
  • Deferred component symbol work for Brs files could run during the initial pass.
  • Some validation state reset happened earlier in the pipeline.

Now (this branch)

  • First validation directly includes all files in scope-context validation.
  • First validation invalidates all user scopes in one shot, instead of deriving/invalidation-by-affected-file.
  • Deferred component creation for Brsfiles is skipped on first validation (still done for XML and subsequent validations).
  • First-validation completion now resets validation bookkeeping in the success path (after a successful run).
  • Scope iteration/invalidation paths were simplified to use all user scopes directly.
  • Scope lookup results per file are cached and cache is cleared when files are added/removed, reducing repeated scope-resolution cost.

Why this improves performance

The first validation run has no meaningful incremental baseline, so trying to compute precise impact sets is mostly overhead.
By switching initial validation to a full-pass strategy, we avoid dependency graph churn and repeated scope/file impact calculations, while preserving incremental behavior for subsequent validations.

Additional branch changes (non-first-validation)

  • Lazy function-name computation in call validation to avoid expensive name building unless a diagnostic actually needs it.
  • Type compatibility fix allowing associative-array/array-like compatibility in interface checks where appropriate.
  • Added test coverage for XML component assocArray usage passed into callfunc interface parameters.

Behavior and risk notes

  • Intended semantic behavior remains the same; this is primarily a performance-path change for cold validation.
  • Main risk area is any workflow depending on first-pass ordering/diagnostic timing rather than final diagnostic set.
  • Revalidation logic remains incremental after first successful validation.

Metrics (Example App)

Before

[04:25:25:781 PM] Validating project finished. (6s524.620ms)
[04:25:25:789 PM] Program.validate metrics:
    wait for previous run------------------------------------------------------- 000.005ms,   1 calls
    before and on programValidate----------------------------------------------- 000.145ms,   1 calls
    get files to be validated--------------------------------------------------- 001.275ms,   1 calls
    add component reference types----------------------------------------------- 000.669ms,   1 calls
    validateFile------------------------------------------------------------- 02s027.987ms, 839 calls
    do deferred component creation---------------------------------------------- 057.636ms, 839 calls
    build component types for any component that changes------------------------ 056.637ms,   1 calls
    track and update type-time and runtime symbol dependencies and changes------ 008.704ms,   1 calls
    tracks changed symbols and prepares files and scopes for validation--------- 317.518ms,   1 calls
    invalidate affected scopes-------------------------------------------------- 026.028ms, 839 calls
    checking scopes to validate------------------------------------------------- 000.214ms,   1 calls
    beforeScopeValidate--------------------------------------------------------- 000.105ms, 294 calls
    validate scope----------------------------------------------------------- 03s955.053ms, 294 calls
    afterValidateScope---------------------------------------------------------- 068.071ms, 294 calls
    detect duplicate component names-------------------------------------------- 001.095ms,   1 calls
    Total-------------------------------------------------------------------- 06s521.140ms,

After

[08:43:54:358 PM] Validating project finished. (5s44.717ms)
[08:43:54:367 PM] Program.validate metrics:
    wait for previous run------------------------------------------------------- 000.005ms,   1 calls
    before and on programValidate----------------------------------------------- 000.128ms,   1 calls
    get files to be validated--------------------------------------------------- 001.148ms,   1 calls
    add component reference types----------------------------------------------- 000.552ms,   1 calls
    validateFile------------------------------------------------------------- 01s618.443ms, 839 calls
    do deferred component creation---------------------------------------------- 000.630ms, 839 calls
    build component types for any component that changes------------------------ 078.657ms,   1 calls
    track and update type-time and runtime symbol dependencies and changes------ 008.971ms,   1 calls
    tracks changed symbols and prepares files and scopes for validation--------- 249.544ms,   1 calls
    invalidating file segments-------------------------------------------------- 001.417ms, 839 calls
    invalidate affected scopes-------------------------------------------------- 000.143ms,   1 calls
    checking scopes to validate------------------------------------------------- 000.177ms,   1 calls
    beforeScopeValidate--------------------------------------------------------- 000.089ms, 294 calls
    validate scope----------------------------------------------------------- 03s028.436ms, 294 calls
    afterValidateScope---------------------------------------------------------- 053.363ms, 294 calls
    detect duplicate component names-------------------------------------------- 000.795ms,   1 calls
    Total-------------------------------------------------------------------- 05s042.497ms,

Roughly, a 20% improvement on first validation time.

@markwpearce markwpearce added this to the v1.0.0 milestone Jun 6, 2026
@markwpearce markwpearce added the create-vsix PRs with this tag will trigger a vsix build on vscode-brightscript-language for every push label Jun 7, 2026
Co-authored-by: TwitchBronBron <2544493+TwitchBronBron@users.noreply.github.com>
Copilot AI requested a review from TwitchBronBron June 8, 2026 18:59
@markwpearce markwpearce added create-package create a temporary npm package on every commit and removed create-vsix PRs with this tag will trigger a vsix build on vscode-brightscript-language for every push labels Jun 9, 2026
@rokucommunity-bot

Copy link
Copy Markdown
Contributor

Hey there! I just built a new temporary npm package based on aee8999. You can download it here or install it by running the following command:

npm install https://github.com/rokucommunity/brighterscript/releases/download/v0.0.0-packages/brighterscript-1.0.0-alpha.52-more-validation-performance-improvements.20260609191606.tgz

@rokucommunity-bot

Copy link
Copy Markdown
Contributor

Hey there! I just built a new temporary npm package based on aee8999. You can download it here or install it by running the following command:

npm install https://github.com/rokucommunity/brighterscript/releases/download/v0.0.0-packages/brighterscript-1.0.0-alpha.52-more-validation-performance-improvements.20260609191614.tgz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

create-package create a temporary npm package on every commit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants