From c9dde4c49f43065a5c7e1d23f02623261f862b2a Mon Sep 17 00:00:00 2001 From: "Jordan Bolton (jobolton)" Date: Mon, 30 Mar 2026 09:43:21 -0500 Subject: [PATCH] Cache knownIdentifiers per scope in validateUnknownIdentifiers Hoist library key computation out of the per-identifier loop and cache the combined known-identifier list per NodeScope instance. Avoids repeated array allocation and spreading when multiple unknown identifiers share the same scope. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- package-lock.json | 4 ++-- package.json | 2 +- .../validate/validateUnknownIdentifiers.ts | 18 ++++++++++++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index dbe1031b..7908a48a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@microsoft/powerquery-language-services", - "version": "0.14.0", + "version": "0.14.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@microsoft/powerquery-language-services", - "version": "0.14.0", + "version": "0.14.1", "license": "MIT", "dependencies": { "@microsoft/powerquery-formatter": "0.3.20", diff --git a/package.json b/package.json index a44f755c..0d0c8d97 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/powerquery-language-services", - "version": "0.14.0", + "version": "0.14.1", "author": "Microsoft", "license": "MIT", "scripts": { diff --git a/src/powerquery-language-services/validate/validateUnknownIdentifiers.ts b/src/powerquery-language-services/validate/validateUnknownIdentifiers.ts index b02acb8a..584fdf5b 100644 --- a/src/powerquery-language-services/validate/validateUnknownIdentifiers.ts +++ b/src/powerquery-language-services/validate/validateUnknownIdentifiers.ts @@ -129,6 +129,14 @@ function findUnknownIdentifiers( const unknownIdentifiers: UnknownIdentifier[] = []; + // Compute library keys once for the entire validation run instead of per-unknown-identifier. + const libraryKeys: ReadonlyArray = LibraryUtils.getDefinitionKeys(validationSettings.library); + + // Cache the combined known-identifier list per NodeScope instance. + // Multiple identifiers in the same scope (e.g. bindings in a let) share the same list, + // avoiding repeated array allocation and spreading. + const knownIdentifiersByScope: Map> = new Map(); + for (const identifierWithNodeScope of identifiersWithNodeScope) { if (ResultUtils.isError(identifierWithNodeScope.triedNodeScope)) { continue; @@ -146,10 +154,12 @@ function findUnknownIdentifiers( identifierLiteral: literal, }) ) { - const knownIdentifiers: ReadonlyArray = [ - ...nodeScope.scopeItemByKey.keys(), - ...LibraryUtils.getDefinitionKeys(validationSettings.library), - ]; + let knownIdentifiers: ReadonlyArray | undefined = knownIdentifiersByScope.get(nodeScope); + + if (knownIdentifiers === undefined) { + knownIdentifiers = [...nodeScope.scopeItemByKey.keys(), ...libraryKeys]; + knownIdentifiersByScope.set(nodeScope, knownIdentifiers); + } const [jaroWinklerScore, suggestion]: [number, string] = calculateJaroWinklers(literal, knownIdentifiers);