perf(typescript-language): memoize deterministic native checker queries - #3418
Draft
JoshuaKGoldberg wants to merge 3 commits into
Draft
JoshuaKGoldberg wants to merge 3 commits into
JoshuaKGoldberg wants to merge 3 commits into
Conversation
The native checker runs out-of-process, so each getTypeAtLocation / getSymbolAtLocation is an IPC round-trip. Many type-aware rules query the same node, so wrap the shared checker in a per-snapshot memoizing proxy (WeakMap keyed by node identity) to collapse those repeats to one round-trip. Results are stable while the snapshot is unchanged (the whole visitor phase). Measured (hyperfine, ESLint-anchored): ~6% faster at high files x many rules (1024 files/272 rules: 2.977s -> 2.855s; 256/272: 922ms -> 868ms), neutral elsewhere. Targets the residual where TS7's per-rule checker IPC trails TS6. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XcCVWAfhF3shCsdz2niEFi
|
❌ Deploy Preview for flint-fyi failed.
|
@flint.fyi/astro
@flint.fyi/astro-language
@flint.fyi/browser
@flint.fyi/cli
@flint.fyi/content-mapper
@flint.fyi/core
@flint.fyi/css
@flint.fyi/css-language
flint
@flint.fyi/json
@flint.fyi/json-language
@flint.fyi/jsx
@flint.fyi/markdown-language
@flint.fyi/md
@flint.fyi/next
@flint.fyi/node
@flint.fyi/nuxt
@flint.fyi/package-json
@flint.fyi/performance
@flint.fyi/plugin-flint
@flint.fyi/react
@flint.fyi/rule-data
@flint.fyi/rule-tester
@flint.fyi/solid
@flint.fyi/spelling
@flint.fyi/svelte
@flint.fyi/svelte-language
@flint.fyi/text-language
@flint.fyi/ts
@flint.fyi/ts-patch
@flint.fyi/typescript-language
@flint.fyi/utils
@flint.fyi/vitest
@flint.fyi/vue
@flint.fyi/vue-language
@flint.fyi/yaml
@flint.fyi/yaml-language
commit: |
…queries Also memoize getTypeOfSymbol, getTypeArguments, getApparentType, getBaseConstraintOfType, isArrayType, isTupleType by their Type/Symbol argument identity. These deterministic-per-snapshot queries are called heavily by type-aware rules; caching them roughly doubles the dedup win at high files x rules (1024/272: -6% -> -10.6% vs baseline). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XcCVWAfhF3shCsdz2niEFi
Extends the memoized checker to every deterministic query rules call (aliased-symbol, contextual type, resolved signature, typeToString, type-from-node, and the two-arg getTypeOfSymbolAtLocation / isTypeAssignableTo), keyed by argument identity. Extracts the wrapper into memoizedChecker.ts. Measured ~1% beyond the prior six-method set and 11-12% over no memoization at 1024 files x 272 rules. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XcCVWAfhF3shCsdz2niEFi
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.
Draft — memoization of the out-of-process native checker.
The TS7 native checker runs out-of-process, so every
getTypeAtLocation/getSymbolAtLocation/ etc. is an IPC round-trip. Type-aware rules frequentlyquery the same node/type/symbol, so wrapping the checker to memoize each
deterministic query by argument identity (for the life of the stable snapshot)
collapses those repeats. Extracted into
memoizedChecker.tsand extended fromthe original 6-method set to every deterministic query rules call:
getTypeAtLocation,getSymbolAtLocation,getApparentType,getBaseConstraintOfType,getTypeArguments,getTypeOfSymbol,isArrayType,isTupleType,getAliasedSymbol,getImmediateAliasedSymbol,getContextualType,getResolvedSignature,getShorthandAssignmentValueSymbol,getTypeFromTypeNode,typeToString(only when called with exactly one argument, so option-bearing overloads
fall through uncached)
getTypeOfSymbolAtLocation,isTypeAssignableToMeasured (hyperfine,
--cache-ignore --skip-formatting --skip-language-reports)End-to-end vs no memoization:
The extended method set adds ~1% over the original 6-method version — small but
consistent across scales and free (correctness verified: identical report
output). Report parity confirmed against the raw checker.
🤖 Generated with Claude Code