Skip to content

Count intersection property names with a plain map and slice - #64876

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

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

Conversation

@jakebailey

@jakebailey Jake Bailey (jakebailey) commented Oct 19, 2026 •

Copy link
Copy Markdown
Member
                  │   old.txt   │             new.txt              │
                  │   sec/op    │   sec/op    vs base              │
Tsc/bluesky          2.430 ± 2%   2.383 ± 3%       ~ (p=0.180 n=6)
Tsc/sentry          10.044 ± 1%   9.931 ± 2%       ~ (p=0.180 n=6)
Tsc/t3code-server    8.038 ± 1%   7.904 ± 2%  -1.67% (p=0.026 n=6)
Tsc/mui-docs         6.518 ± 2%   6.138 ± 3%  -5.83% (p=0.002 n=6)
geomean              5.980        5.821       -2.66%

                  │   old.txt    │              new.txt               │
                  │    rss-B     │    rss-B      vs base              │
Tsc/bluesky         1.189Gi ± 3%   1.176Gi ± 4%       ~ (p=0.485 n=6)
Tsc/sentry          3.271Gi ± 4%   3.215Gi ± 6%       ~ (p=0.240 n=6)
Tsc/t3code-server   2.753Gi ± 5%   2.776Gi ± 6%       ~ (p=0.937 n=6)
Tsc/mui-docs        2.362Gi ± 7%   2.314Gi ± 5%       ~ (p=0.699 n=6)
geomean             2.242Gi        2.220Gi       -0.99%

                  │   old.txt    │              new.txt               │
                  │    heap-B    │    heap-B     vs base              │
Tsc/bluesky         915.2Mi ± 0%   914.9Mi ± 0%       ~ (p=0.699 n=6)
Tsc/sentry          2.483Gi ± 0%   2.482Gi ± 0%       ~ (p=0.818 n=6)
Tsc/t3code-server   2.179Gi ± 0%   2.180Gi ± 0%       ~ (p=0.394 n=6)
Tsc/mui-docs        1.732Gi ± 0%   1.732Gi ± 0%       ~ (p=0.310 n=6)
geomean             1.701Gi        1.701Gi       -0.00%

This will conflict with #64815 to some extent

Deciding whether an intersection reduces to never counts how many
constituents declare each property name. The ordered map used for
this is a general-purpose structure that does more bookkeeping per
operation than this hot path needs, and each property costs a lookup
and an assignment. On mui-docs this shows up as a few percent of
single-checker time.

Count into a slice of entries indexed by a plain string map instead.
The slice keeps first-occurrence order for the reduction check, and
the first constituent's names are inserted without a lookup since
property names are already unique within a type.

                  │    old     │                new                │
                  │   sec/op   │   sec/op     vs base              │
Tsc/bluesky         3.179 ± 1%   3.133 ±  1%  -1.45% (p=0.039 n=6)
Tsc/sentry          12.90 ± 7%   12.77 ± 17%       ~ (p=0.818 n=6)
Tsc/t3code-server   16.85 ± 3%   16.80 ±  3%       ~ (p=0.937 n=6)
Tsc/mui-docs        8.536 ± 3%   8.152 ±  1%  -4.50% (p=0.002 n=6)
geomean             8.763        8.604        -1.81%

                  │     old      │                new                 │
                  │    rss-B     │    rss-B      vs base              │
Tsc/bluesky         1.439Gi ± 2%   1.417Gi ± 1%       ~ (p=0.093 n=6)
Tsc/sentry          4.566Gi ± 4%   4.504Gi ± 4%       ~ (p=0.937 n=6)
Tsc/t3code-server   4.488Gi ± 5%   4.344Gi ± 9%       ~ (p=0.485 n=6)
Tsc/mui-docs        3.535Gi ± 4%   3.391Gi ± 4%       ~ (p=0.065 n=6)
geomean             3.195Gi        3.114Gi       -2.55%

                  │     old      │                new                 │
                  │    heap-B    │    heap-B     vs base              │
Tsc/bluesky         1.153Gi ± 0%   1.152Gi ± 0%       ~ (p=0.394 n=6)
Tsc/sentry          3.620Gi ± 0%   3.622Gi ± 0%       ~ (p=0.485 n=6)
Tsc/t3code-server   3.761Gi ± 0%   3.762Gi ± 0%       ~ (p=0.310 n=6)
Tsc/mui-docs        2.641Gi ± 0%   2.641Gi ± 0%       ~ (p=0.818 n=6)
geomean             2.537Gi        2.537Gi       +0.01%
Copilot AI balanced review requested due to automatic review settings October 19, 2026 18:45
@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

Static review found no blocking issues in this localized refactor; automated validation was not run.

1 open issue
What changed in this PR

Optimizes property counting when the checker determines whether an intersection reduces to never, while preserving first-occurrence order.

Changes:

  • Replaces the ordered map with a name-to-index map and count slice.
  • Skips lookups for the first constituent’s properties.
  • Updates counting and workspace-reuse tests.
File Description
tsc/​internal/​checker/​utilities.go Implements map-and-slice property counts.
tsc/​internal/​checker/​types_test.go Adapts counting and reuse assertions.
tsc/​internal/​checker/​checker.go Uses the new counting operations during intersection reduction.

Review effort: Balanced

Comment on lines +937 to +938
entries []propertyCount
indices map[string]int32
@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,611k (± 0.07%) 113,461k (± 0.04%) -150k (- 0.13%) 113,372k 113,611k p=0.003 n=12
Memory Allocs 2,212,588 (± 0.00%) 2,212,505 (± 0.01%) ~ 2,212,245 2,212,961 p=0.266 n=12
Config Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Parse Time 0.039s (± 4.10%) 0.040s (± 3.57%) ~ 0.037s 0.044s p=0.480 n=12
Bind Time 0.014s (± 9.58%) 0.014s (± 8.31%) ~ 0.011s 0.017s p=0.830 n=12
Check Time 0.467s (± 0.82%) 0.471s (± 0.64%) ~ 0.465s 0.480s p=0.070 n=12
Emit Time 0.275s (± 2.12%) 0.269s (± 2.63%) ~ 0.253s 0.285s p=0.247 n=12
Total Time 0.802s (± 0.95%) 0.800s (± 0.82%) ~ 0.787s 0.818s p=0.681 n=12
angular-1 - native
Errors 3 3 ~ ~ ~ p=1.000 n=12
Symbols 847,269 (± 0.06%) 847,364 (± 0.08%) ~ 845,490 849,037 p=0.843 n=12
Types 247,031 (± 0.00%) 247,035 (± 0.00%) +3 (+ 0.00%) 247,029 247,045 p=0.016 n=12
Memory Used 596,362k (± 0.02%) 596,381k (± 0.03%) ~ 595,851k 596,863k p=0.799 n=12
Memory Allocs 13,139,205 (± 0.03%) 13,148,114 (± 0.07%) ~ 13,134,175 13,175,783 p=0.078 n=12
Config Time 0.017s (± 1.45%) 0.017s (± 1.70%) ~ 0.016s 0.017s p=1.000 n=12
Parse Time 0.221s (± 1.77%) 0.228s (± 2.77%) ~ 0.214s 0.242s p=0.091 n=12
Bind Time 0.081s (±11.65%) 0.074s (±15.34%) ~ 0.058s 0.102s p=0.213 n=12
Check Time 0s 0s ~ ~ ~ p=1.000 n=12
Emit Time 1.561s (± 1.37%) 1.577s (± 1.32%) ~ 1.532s 1.647s p=0.325 n=12
Total Time 1.902s (± 1.39%) 1.916s (± 1.04%) ~ 1.880s 1.971s p=0.434 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,694k (± 0.03%) 2,626,152k (± 0.05%) ~ 2,622,356k 2,629,755k p=0.052 n=12
Memory Allocs 27,713,795 (± 0.08%) 27,713,469 (± 0.05%) ~ 27,661,441 27,738,171 p=0.671 n=12
Config Time 0.017s (± 1.70%) 0.017s (± 1.45%) ~ 0.016s 0.017s p=1.000 n=12
Parse Time 0.466s (± 3.53%) 0.478s (± 3.09%) ~ 0.440s 0.513s p=0.202 n=12
Bind Time 0.002s 0.002s ~ ~ ~ p=1.000 n=12
Check Time 7.222s (± 0.13%) 6.973s (± 0.62%) 🟩-0.249s (- 3.45%) 6.855s 7.125s p=0.000 n=12
Emit Time 0.566s (±11.48%) 0.524s (±13.72%) ~ 0.417s 0.661s p=0.352 n=12
Total Time 9.012s (± 0.82%) 8.726s (± 1.21%) 🟩-0.286s (- 3.17%) 8.532s 8.929s p=0.000 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,311,304k (± 0.49%) 1,316,572k (± 0.55%) ~ 1,300,268k 1,343,645k p=0.143 n=12
Memory Allocs 78,204,684 (± 0.14%) 78,244,813 (± 0.10%) ~ 77,942,738 78,401,237 p=0.671 n=12
Config Time 0.003s (±12.31%) 0.003s (± 9.48%) ~ 0.003s 0.004s p=1.000 n=12
Parse Time 0.255s (± 2.42%) 0.251s (± 1.44%) ~ 0.242s 0.260s p=0.181 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 1.679s (± 0.46%) 1.675s (± 0.52%) ~ 1.648s 1.696s p=0.451 n=12
Emit Time 0.290s (± 3.30%) 0.304s (± 3.61%) 🔻+0.015s (+ 5.06%) 0.286s 0.345s p=0.027 n=12
Total Time 19.823s (± 0.63%) 19.908s (± 0.71%) ~ 19.415s 20.223s p=0.319 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,491k (± 0.04%) 247,503k (± 0.02%) ~ 247,424k 247,698k p=1.000 n=12
Memory Allocs 4,329,337 (± 0.01%) 4,330,004 (± 0.01%) +667 (+ 0.02%) 4,328,447 4,330,998 p=0.045 n=12
Config Time 0.001s 0.001s ~ ~ ~ p=1.000 n=12
Parse Time 0.112s (± 4.22%) 0.114s (± 4.07%) ~ 0.099s 0.124s p=0.400 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 0.965s (± 0.58%) 0.968s (± 0.74%) ~ 0.954s 0.985s p=0.284 n=12
Emit Time 0.146s (± 3.46%) 0.154s (± 4.88%) ~ 0.134s 0.170s p=0.070 n=12
Total Time 1.276s (± 0.74%) 1.294s (± 0.85%) +0.018s (+ 1.41%) 1.271s 1.322s p=0.027 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,252k (± 0.02%) 215,226k (± 0.02%) ~ 215,082k 215,331k p=0.272 n=12
Memory Allocs 1,401,488 (± 0.02%) 1,401,793 (± 0.01%) ~ 1,401,399 1,402,406 p=0.052 n=12
Config Time 0.000s 0.000s (±146.91%) ~ 0.000s 0.001s p=0.478 n=12
Parse Time 0.097s (± 3.48%) 0.098s (± 2.60%) ~ 0.093s 0.105s p=0.467 n=12
Bind Time 0.043s (± 6.32%) 0.042s (± 7.29%) ~ 0.032s 0.051s p=0.639 n=12
Check Time 0.745s (± 0.86%) 0.746s (± 0.57%) ~ 0.734s 0.757s p=0.898 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 0.900s (± 0.90%) 0.902s (± 0.62%) ~ 0.889s 0.918s p=0.504 n=12
vscode - native
Errors 396 396 ~ ~ ~ p=1.000 n=12
Symbols 12,501,426 12,501,426 ~ ~ ~ p=1.000 n=12
Types 4,091,299 4,091,299 ~ ~ ~ p=1.000 n=12
Memory Used 5,843,208k (± 0.01%) 5,843,893k (± 0.02%) ~ 5,841,588k 5,846,890k p=0.242 n=12
Memory Allocs 59,416,904 (± 0.01%) 59,424,090 (± 0.02%) ~ 59,410,476 59,471,687 p=0.078 n=12
Config Time 0.076s (± 0.48%) 0.076s (± 0.24%) ~ 0.076s 0.077s p=0.590 n=12
Parse Time 1.826s (± 2.06%) 1.803s (± 2.00%) ~ 1.742s 1.906s p=0.434 n=12
Bind Time 0.641s (±13.90%) 0.712s (±12.79%) ~ 0.527s 0.923s p=0.198 n=12
Check Time 14.703s (± 0.95%) 14.583s (± 0.99%) -0.119s (- 0.81%) 14.330s 14.847s p=0.050 n=12
Emit Time 5.322s (± 6.90%) 5.266s (± 6.37%) ~ 4.502s 5.920s p=0.713 n=12
Total Time 22.653s (± 1.32%) 22.531s (± 1.05%) ~ 21.993s 22.995s p=0.590 n=12
webpack - native
Errors 598 598 ~ ~ ~ p=1.000 n=12
Symbols 1,398,302 1,398,302 ~ ~ ~ p=1.000 n=12
Types 670,900 670,900 ~ ~ ~ p=1.000 n=12
Memory Used 885,544k (± 0.02%) 885,710k (± 0.02%) ~ 885,190k 885,997k p=0.114 n=12
Memory Allocs 6,928,895 (± 0.04%) 6,928,483 (± 0.03%) ~ 6,924,793 6,936,985 p=0.799 n=12
Config Time 0.009s 0.009s ~ ~ ~ p=1.000 n=12
Parse Time 0.317s (± 2.37%) 0.322s (± 3.67%) ~ 0.295s 0.349s p=0.451 n=12
Bind Time 0.079s (± 7.54%) 0.077s (± 3.36%) ~ 0.070s 0.085s p=1.000 n=12
Check Time 2.968s (± 0.25%) 2.965s (± 0.50%) ~ 2.934s 3.012s p=0.486 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 3.412s (± 0.33%) 3.411s (± 0.45%) ~ 3.364s 3.445s p=0.989 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,880k (± 0.02%) 471,904k (± 0.02%) ~ 471,677k 472,246k p=0.671 n=12
Memory Allocs 4,221,665 (± 0.10%) 4,222,310 (± 0.08%) ~ 4,210,454 4,229,639 p=0.755 n=12
Config Time 0.003s 0.003s (± 8.64%) ~ 0.002s 0.003s p=0.478 n=12
Parse Time 0.134s (± 3.56%) 0.140s (± 2.86%) ~ 0.125s 0.148s p=0.085 n=12
Bind Time 0.045s (±12.71%) 0.044s (±17.39%) ~ 0.033s 0.065s p=0.527 n=12
Check Time 1.093s (± 0.99%) 1.092s (± 0.93%) ~ 1.070s 1.119s p=0.921 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 1.285s (± 0.86%) 1.287s (± 1.01%) ~ 1.251s 1.316s p=0.989 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