Skip to content

Compare names before symbols when matching flow references - #64868

Open
Jake Bailey (jakebailey) wants to merge 1 commit into
microsoft:mainfrom
jakebailey:perf/flow-name-compare
Open

Jake Bailey (jakebailey) wants to merge 1 commit into
microsoft:mainfrom
jakebailey:perf/flow-name-compare

Conversation

@jakebailey

Copy link
Copy Markdown
Member

Narrowing a reference walks back through every assignment and variable declaration on its flow path, and asks whether each one assigns the reference. For a declaration target that meant loading the declaration's symbol and looking up its late-bound and merged symbols, which is mostly cache misses on unrelated symbols. In long functions this dominated flow analysis.

A declaration's symbol is named by its identifier, so a reference with a different name can never match it. Comparing names first skips the symbol work for nearly every unrelated declaration.

--checkers 4, n=8, default GC settings:

                  │  before    │              after               │
                  │   sec/op   │   sec/op    vs base              │
Tsc/bluesky         2.767 ± 1%   2.752 ± 2%       ~ (p=0.314 n=8)
Tsc/sentry          10.78 ± 2%   10.76 ± 2%       ~ (p=0.701 n=8)
Tsc/t3code-server   13.50 ± 4%   12.57 ± 1%  -6.85% (p=0.000 n=8)
geomean             7.384        7.194       -2.58%

                  │   before     │               after                │
                  │    rss-B     │    rss-B      vs base              │
Tsc/bluesky         1.183Gi ± 2%   1.181Gi ± 3%       ~ (p=0.878 n=8)
Tsc/sentry          3.549Gi ± 6%   3.481Gi ± 5%       ~ (p=0.721 n=8)
Tsc/t3code-server   2.880Gi ± 2%   2.849Gi ± 2%       ~ (p=0.279 n=8)
geomean             2.296Gi        2.271Gi       -1.06%

                  │   before     │               after                │
                  │    heap-B    │    heap-B     vs base              │
Tsc/bluesky         934.5Mi ± 0%   934.8Mi ± 0%  +0.04% (p=0.031 n=8)
Tsc/sentry          2.608Gi ± 0%   2.608Gi ± 0%       ~ (p=0.505 n=8)
Tsc/t3code-server   2.301Gi ± 0%   2.302Gi ± 0%       ~ (p=0.328 n=8)
geomean             1.763Gi        1.763Gi       +0.03%

Narrowing a reference walks back through every assignment and
variable declaration on its flow path, and asks whether each one
assigns the reference. For a declaration target that meant loading
the declaration's symbol and looking up its late-bound and merged
symbols, which is mostly cache misses on unrelated symbols. In long
functions this dominated flow analysis.

A declaration's symbol is named by its identifier, so a reference
with a different name can never match it. Comparing names first
skips the symbol work for nearly every unrelated declaration.

--checkers 4, n=8, default GC settings:

                  │  before    │              after               │
                  │   sec/op   │   sec/op    vs base              │
Tsc/bluesky         2.767 ± 1%   2.752 ± 2%       ~ (p=0.314 n=8)
Tsc/sentry          10.78 ± 2%   10.76 ± 2%       ~ (p=0.701 n=8)
Tsc/t3code-server   13.50 ± 4%   12.57 ± 1%  -6.85% (p=0.000 n=8)
geomean             7.384        7.194       -2.58%

                  │   before     │               after                │
                  │    rss-B     │    rss-B      vs base              │
Tsc/bluesky         1.183Gi ± 2%   1.181Gi ± 3%       ~ (p=0.878 n=8)
Tsc/sentry          3.549Gi ± 6%   3.481Gi ± 5%       ~ (p=0.721 n=8)
Tsc/t3code-server   2.880Gi ± 2%   2.849Gi ± 2%       ~ (p=0.279 n=8)
geomean             2.296Gi        2.271Gi       -1.06%

                  │   before     │               after                │
                  │    heap-B    │    heap-B     vs base              │
Tsc/bluesky         934.5Mi ± 0%   934.8Mi ± 0%  +0.04% (p=0.031 n=8)
Tsc/sentry          2.608Gi ± 0%   2.608Gi ± 0%       ~ (p=0.505 n=8)
Tsc/t3code-server   2.301Gi ± 0%   2.302Gi ± 0%       ~ (p=0.328 n=8)
geomean             1.763Gi        1.763Gi       +0.03%
Copilot AI balanced review requested due to automatic review settings October 19, 2026 17:10
@github-project-automation github-project-automation Bot moved this to Not started in PR Backlog Oct 19, 2026
@typescript-automation typescript-automation Bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Oct 19, 2026
@jakebailey

Copy link
Copy Markdown
Member Author

TypeScript Bot (@typescript-bot) perf test this faster

@typescript-automation

typescript-automation Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
perf test this faster ✅ Started 👀 Results

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The narrowly scoped optimization preserves matching behavior, with no blocking issues identified.

No open issues 🎉

What changed in this PR

Optimizes flow-reference matching in the native TypeScript checker by avoiding symbol lookups for unrelated declarations.

Changes:

  • Rejects variable declarations and binding elements with different identifier names before resolving symbols.
  • Preserves symbol-based matching for remaining cases.
File Description
tsc/​internal/​checker/​flow.go Adds an early name check when matching declaration targets.

Review effort: Balanced

@typescript-automation

Copy link
Copy Markdown
Contributor

Jake Bailey (@jakebailey)
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - native
Errors 41 41 ~ ~ ~ p=1.000 n=12
Symbols 115,276 115,276 ~ ~ ~ p=1.000 n=12
Types 79,613 79,613 ~ ~ ~ p=1.000 n=12
Memory Used 113,543k (± 0.06%) 113,517k (± 0.05%) ~ 113,408k 113,727k p=0.504 n=12
Memory Allocs 2,212,516 (± 0.00%) 2,212,674 (± 0.01%) ~ 2,212,391 2,213,242 p=0.193 n=12
Config Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Parse Time 0.040s (± 2.80%) 0.040s (± 3.67%) ~ 0.036s 0.043s p=0.875 n=12
Bind Time 0.014s (± 9.48%) 0.013s (±10.03%) ~ 0.011s 0.018s p=0.907 n=12
Check Time 0.470s (± 0.84%) 0.468s (± 0.63%) ~ 0.460s 0.478s p=0.338 n=12
Emit Time 0.267s (± 2.04%) 0.268s (± 2.46%) ~ 0.255s 0.287s p=0.943 n=12
Total Time 0.798s (± 0.78%) 0.796s (± 1.09%) ~ 0.785s 0.830s p=0.451 n=12
angular-1 - native
Errors 3 3 ~ ~ ~ p=1.000 n=12
Symbols 846,863 (± 0.07%) 846,687 (± 0.07%) ~ 845,104 848,236 p=0.887 n=12
Types 247,033 (± 0.00%) 247,031 (± 0.00%) -2 (- 0.00%) 247,028 247,034 p=0.031 n=12
Memory Used 596,350k (± 0.03%) 596,435k (± 0.02%) ~ 596,071k 596,758k p=0.272 n=12
Memory Allocs 13,148,067 (± 0.10%) 13,146,610 (± 0.07%) ~ 13,136,314 13,183,229 p=0.143 n=12
Config Time 0.017s (± 1.95%) 0.017s (± 1.86%) ~ 0.016s 0.017s p=1.000 n=12
Parse Time 0.220s (± 2.61%) 0.229s (± 4.13%) 🔻+0.009s (+ 4.01%) 0.212s 0.269s p=0.043 n=12
Bind Time 0.082s (±12.61%) 0.076s (±16.22%) ~ 0.058s 0.113s p=0.369 n=12
Check Time 0s 0s ~ ~ ~ p=1.000 n=12
Emit Time 1.556s (± 1.61%) 1.574s (± 1.24%) ~ 1.526s 1.614s p=0.285 n=12
Total Time 1.895s (± 1.37%) 1.914s (± 1.07%) ~ 1.870s 1.960s p=0.272 n=12
mui-docs - native
Errors 11,405 11,405 ~ ~ ~ p=1.000 n=12
Symbols 4,331,983 4,331,983 ~ ~ ~ p=1.000 n=12
Types 1,370,520 1,370,520 ~ ~ ~ p=1.000 n=12
Memory Used 2,624,368k (± 0.04%) 2,625,409k (± 0.03%) ~ 2,622,669k 2,627,563k p=0.143 n=12
Memory Allocs 27,699,452 (± 0.07%) 27,720,827 (± 0.05%) ~ 27,678,993 27,742,391 p=0.089 n=12
Config Time 0.017s (± 1.07%) 0.017s (± 1.45%) ~ 0.016s 0.017s p=1.000 n=12
Parse Time 0.485s (± 2.75%) 0.469s (± 2.16%) ~ 0.441s 0.486s p=0.124 n=12
Bind Time 0.002s 0.002s ~ ~ ~ p=1.000 n=12
Check Time 7.245s (± 0.53%) 7.227s (± 0.53%) ~ 7.142s 7.337s p=0.370 n=12
Emit Time 0.520s (±13.58%) 0.536s (±12.26%) ~ 0.416s 0.660s p=0.809 n=12
Total Time 9.005s (± 0.76%) 8.997s (± 0.60%) ~ 8.825s 9.080s p=0.724 n=12
strada-build-src - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 1,388,680 1,388,680 ~ ~ ~ p=1.000 n=12
Types 441,862 441,862 ~ ~ ~ p=1.000 n=12
Memory Used 1,312,335k (± 0.51%) 1,316,392k (± 0.55%) ~ 1,299,858k 1,336,090k p=0.319 n=12
Memory Allocs 78,231,968 (± 0.12%) 78,294,763 (± 0.06%) ~ 78,203,205 78,421,144 p=0.378 n=12
Config Time 0.004s (± 9.04%) 0.004s (±12.64%) ~ 0.002s 0.005s p=0.460 n=12
Parse Time 0.253s (± 1.55%) 0.254s (± 1.99%) ~ 0.241s 0.267s p=0.434 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 1.674s (± 0.57%) 1.660s (± 0.54%) -0.014s (- 0.84%) 1.636s 1.681s p=0.018 n=12
Emit Time 0.299s (± 3.57%) 0.302s (± 4.80%) ~ 0.270s 0.334s p=0.898 n=12
Total Time 19.854s (± 0.37%) 19.741s (± 0.59%) ~ 19.325s 19.989s p=0.143 n=12
strada-compiler - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 334,953 334,953 ~ ~ ~ p=1.000 n=12
Types 197,616 197,616 ~ ~ ~ p=1.000 n=12
Memory Used 247,508k (± 0.04%) 247,494k (± 0.03%) ~ 247,290k 247,660k p=0.590 n=12
Memory Allocs 4,329,543 (± 0.01%) 4,329,384 (± 0.01%) ~ 4,328,490 4,330,503 p=0.443 n=12
Config Time 0.001s 0.001s ~ ~ ~ p=1.000 n=12
Parse Time 0.114s (± 3.35%) 0.115s (± 5.44%) ~ 0.097s 0.128s p=0.599 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 0.961s (± 0.45%) 0.951s (± 0.46%) -0.009s (- 0.98%) 0.940s 0.966s p=0.005 n=12
Emit Time 0.148s (± 4.17%) 0.153s (± 6.71%) ~ 0.120s 0.173s p=0.298 n=12
Total Time 1.274s (± 0.64%) 1.276s (± 1.15%) ~ 1.242s 1.318s p=0.660 n=12
ts-pre-modules - native
Errors 87 87 ~ ~ ~ p=1.000 n=12
Symbols 303,834 303,834 ~ ~ ~ p=1.000 n=12
Types 181,663 181,663 ~ ~ ~ p=1.000 n=12
Memory Used 215,213k (± 0.02%) 215,261k (± 0.01%) ~ 215,191k 215,320k p=0.114 n=12
Memory Allocs 1,401,666 (± 0.02%) 1,401,515 (± 0.02%) ~ 1,400,773 1,401,982 p=0.410 n=12
Config Time 0.000s (±217.90%) 0.000s ~ ~ ~ p=1.000 n=12
Parse Time 0.097s (± 3.25%) 0.099s (± 4.37%) ~ 0.089s 0.108s p=0.599 n=12
Bind Time 0.041s (± 8.59%) 0.042s (± 8.73%) ~ 0.035s 0.051s p=0.787 n=12
Check Time 0.742s (± 0.69%) 0.740s (± 0.76%) ~ 0.725s 0.757s p=0.339 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 0.895s (± 0.65%) 0.896s (± 0.79%) ~ 0.881s 0.913s p=0.944 n=12
vscode - native
Errors 396 396 ~ ~ ~ p=1.000 n=12
Symbols 12,386,876 12,386,876 ~ ~ ~ p=1.000 n=12
Types 4,049,733 4,049,733 ~ ~ ~ p=1.000 n=12
Memory Used 5,820,990k (± 0.01%) 5,820,941k (± 0.02%) ~ 5,818,727k 5,823,619k p=0.887 n=12
Memory Allocs 59,185,766 (± 0.01%) 59,187,497 (± 0.02%) ~ 59,173,901 59,241,391 p=0.671 n=12
Config Time 0.076s (± 0.35%) 0.076s (± 0.24%) ~ 0.075s 0.076s p=1.000 n=12
Parse Time 1.829s (± 1.58%) 1.852s (± 2.55%) ~ 1.745s 1.975s p=0.468 n=12
Bind Time 0.683s (±11.44%) 0.657s (±14.94%) ~ 0.512s 0.893s p=0.660 n=12
Check Time 15.596s (± 1.05%) 15.578s (± 1.19%) ~ 15.210s 15.885s p=0.266 n=12
Emit Time 5.619s (± 6.18%) 5.398s (± 5.68%) ~ 4.586s 6.201s p=0.219 n=12
Total Time 23.898s (± 1.07%) 23.648s (± 0.91%) ~ 22.877s 24.239s p=0.078 n=12
webpack - native
Errors 598 598 ~ ~ ~ p=1.000 n=12
Symbols 1,398,279 1,398,279 ~ ~ ~ p=1.000 n=12
Types 670,934 670,934 ~ ~ ~ p=1.000 n=12
Memory Used 885,610k (± 0.01%) 885,755k (± 0.02%) ~ 885,389k 886,368k p=0.266 n=12
Memory Allocs 6,928,614 (± 0.03%) 6,926,996 (± 0.02%) ~ 6,925,541 6,935,063 p=0.114 n=12
Config Time 0.009s 0.009s ~ ~ ~ p=1.000 n=12
Parse Time 0.309s (± 2.39%) 0.323s (± 2.84%) 🔻+0.014s (+ 4.47%) 0.299s 0.348s p=0.027 n=12
Bind Time 0.079s (± 6.81%) 0.078s (± 5.58%) ~ 0.070s 0.090s p=0.831 n=12
Check Time 2.967s (± 0.41%) 2.860s (± 0.24%) 🟩-0.107s (- 3.61%) 2.843s 2.877s p=0.000 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 3.402s (± 0.41%) 3.308s (± 0.46%) -0.094s (- 2.77%) 3.260s 3.349s p=0.000 n=12
xstate-main - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 1,060,810 1,060,810 ~ ~ ~ p=1.000 n=12
Types 389,671 389,671 ~ ~ ~ p=1.000 n=12
Memory Used 471,811k (± 0.02%) 471,917k (± 0.03%) ~ 471,608k 472,207k p=0.160 n=12
Memory Allocs 4,220,158 (± 0.10%) 4,222,590 (± 0.11%) ~ 4,212,608 4,233,632 p=0.590 n=12
Config Time 0.003s (±11.61%) 0.003s (± 8.64%) ~ 0.002s 0.003s p=0.640 n=12
Parse Time 0.138s (± 2.93%) 0.135s (± 3.08%) ~ 0.126s 0.149s p=0.246 n=12
Bind Time 0.044s (±16.00%) 0.044s (±17.20%) ~ 0.033s 0.068s p=1.000 n=12
Check Time 1.090s (± 0.87%) 1.082s (± 0.47%) ~ 1.068s 1.096s p=0.193 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 1.284s (± 1.04%) 1.273s (± 0.76%) ~ 1.249s 1.298s p=0.181 n=12
System info unknown
Hosts
  • native
Scenarios
  • Compiler-Unions - native
  • angular-1 - native
  • mui-docs - native
  • strada-build-src - native
  • strada-compiler - native
  • ts-pre-modules - native
  • vscode - native
  • webpack - native
  • xstate-main - native
Benchmark Name Iterations
Current pr 12
Baseline baseline 12

Developer Information:

Download Benchmarks

This branch has not been deployed

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

Labels

Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

Status: Not started

Development

Successfully merging this pull request may close these issues.

2 participants