Skip to content

Add cache to getSimplifiedConditionalType - #64648

Merged
Anders Hejlsberg (ahejlsberg) merged 3 commits into
mainfrom
cacheSimplifiedConditionalTypes
Oct 14, 2026
Merged

Anders Hejlsberg (ahejlsberg) merged 3 commits into
mainfrom
cacheSimplifiedConditionalTypes

Conversation

@ahejlsberg

Copy link
Copy Markdown
Member

With this PR we consistently cache results in getSimplifiedType. Previously, we cached results for indexed access types but not conditional types. Found in performance experiments by Bun team.

Copilot AI balanced review requested due to automatic review settings October 5, 2026 19:34
@typescript-automation typescript-automation Bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Oct 5, 2026
@ahejlsberg

Copy link
Copy Markdown
Member Author

TypeScript Bot (@typescript-bot) test it

@typescript-automation

typescript-automation Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

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

Command Status Results
test top400 ✅ Started ✅ Results
user test this ✅ Started ✅ Results
run dt ✅ Started ✅ Results
perf test this faster ✅ Started 👀 Results

@typescript-automation

Copy link
Copy Markdown
Contributor

Hey Anders Hejlsberg (@ahejlsberg), the results of running the DT tests are ready.

Everything looks the same!

You can check the log here.

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.

Copilot review overview

🟡 Changes recommended

The cache must distinguish read and write simplification modes to avoid reusing incorrect results.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Adds caching for simplified conditional types to improve checker performance.

Changes:

  • Adds a conditional-type cache kind.
  • Splits cached orchestration from simplification logic.
File Description
tsc/​internal/​checker/​checker.go Caches conditional-type simplification results.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread tsc/internal/checker/checker.go Outdated
}

func (c *Checker) getSimplifiedConditionalType(t *Type, writing bool) *Type {
key := CachedTypeKey{kind: CachedTypeKindSimplifiedConditionalType, typeId: t.id}

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.

regression tests for the above:

type Value<T extends { a: string; b: number }> = T["a" | "b"] extends unknown
  ? T["a" | "b"]
  : never;

function test<T extends { a: string; b: number }>(value: Value<T>, a: T["a"]) {
  const read: T["a"] | T["b"] = value;
  const write: Value<T> = a; // errors
}

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.

Implemented separate read/write cache kinds and added regression coverage. Commit: dbb752eff.

@typescript-automation

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg)
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 141,886k (± 0.52%) 141,762k (± 0.38%) ~ 140,749k 143,935k p=0.590 n=12
Memory Allocs 2,193,643 (± 0.01%) 2,193,559 (± 0.01%) ~ 2,193,188 2,193,961 p=0.478 n=12
Config Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Parse Time 0.041s (± 3.00%) 0.042s (± 3.35%) ~ 0.039s 0.046s p=0.612 n=12
Bind Time 0.012s (±14.80%) 0.012s (± 9.22%) ~ 0.010s 0.016s p=0.603 n=12
Check Time 0.497s (± 0.86%) 0.495s (± 0.61%) ~ 0.487s 0.502s p=0.448 n=12
Emit Time 0.272s (± 1.97%) 0.267s (± 2.00%) ~ 0.248s 0.279s p=0.325 n=12
Total Time 0.829s (± 0.88%) 0.823s (± 0.76%) ~ 0.808s 0.841s p=0.163 n=12
angular-1 - native
Errors 3 3 ~ ~ ~ p=1.000 n=12
Symbols 847,041 (± 0.06%) 847,021 (± 0.07%) ~ 845,274 848,203 p=0.887 n=12
Types 249,941 (± 0.00%) 249,941 (± 0.00%) ~ 249,937 249,950 p=0.444 n=12
Memory Used 789,597k (± 0.08%) 789,537k (± 0.09%) ~ 787,622k 791,463k p=0.977 n=12
Memory Allocs 12,867,863 (± 0.07%) 12,865,722 (± 0.06%) ~ 12,854,690 12,892,669 p=0.590 n=12
Config Time 0.017s (± 1.95%) 0.017s +0.000s (+ 2.51%) ~ ~ p=0.037 n=12
Parse Time 0.255s (± 3.01%) 0.259s (± 2.28%) ~ 0.239s 0.269s p=0.325 n=12
Bind Time 0.066s (±17.51%) 0.061s (±11.68%) 🟩-0.005s (- 7.57%) 0.057s 0.097s p=0.029 n=12
Check Time 0s 0s ~ ~ ~ p=1.000 n=12
Emit Time 1.601s (± 0.96%) 1.593s (± 0.74%) ~ 1.565s 1.630s p=0.561 n=12
Total Time 1.951s (± 1.09%) 1.941s (± 0.71%) ~ 1.906s 1.995s p=0.765 n=12
mui-docs - native
Errors 11,405 11,405 ~ ~ ~ p=1.000 n=12
Symbols 4,351,480 4,351,480 ~ ~ ~ p=1.000 n=12
Types 1,380,970 1,380,970 ~ ~ ~ p=1.000 n=12
Memory Used 2,975,362k (± 0.04%) 2,974,730k (± 0.04%) ~ 2,970,822k 2,978,067k p=0.671 n=12
Memory Allocs 32,840,597 (± 0.05%) 32,787,989 (± 0.05%) -52,608 (- 0.16%) 32,750,727 32,825,128 p=0.000 n=12
Config Time 0.017s (± 1.86%) 0.017s (± 1.70%) ~ 0.016s 0.017s p=1.000 n=12
Parse Time 0.504s (± 2.33%) 0.500s (± 2.13%) ~ 0.471s 0.523s p=0.660 n=12
Bind Time 0.002s 0.002s ~ ~ ~ p=1.000 n=12
Check Time 8.504s (± 0.87%) 8.481s (± 0.72%) ~ 8.289s 8.608s p=0.504 n=12
Emit Time 0.440s (± 7.01%) 0.434s (± 3.42%) ~ 0.419s 0.496s p=0.221 n=12
Total Time 10.228s (± 0.56%) 10.203s (± 0.42%) ~ 10.084s 10.322s p=0.401 n=12
strada-build-src - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 1,390,229 1,390,229 ~ ~ ~ p=1.000 n=12
Types 441,498 441,498 ~ ~ ~ p=1.000 n=12
Memory Used 1,694,289k (± 1.04%) 1,689,782k (± 1.03%) ~ 1,648,439k 1,724,345k p=0.755 n=12
Memory Allocs 92,233,428 (± 0.10%) 92,212,096 (± 0.17%) ~ 91,795,070 92,518,137 p=0.713 n=12
Config Time 0.003s (±14.26%) 0.003s (±12.31%) ~ 0.002s 0.004s p=0.496 n=12
Parse Time 0.197s (± 4.94%) 0.203s (± 3.69%) ~ 0.184s 0.218s p=0.325 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 1.810s (± 0.59%) 1.803s (± 0.61%) ~ 1.775s 1.836s p=0.340 n=12
Emit Time 0.285s (± 4.91%) 0.303s (± 5.69%) ~ 0.261s 0.351s p=0.075 n=12
Total Time 23.396s (± 0.79%) 23.572s (± 0.78%) ~ 23.182s 24.077s p=0.219 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 313,310k (± 0.03%) 313,334k (± 0.03%) ~ 313,130k 313,597k p=0.843 n=12
Memory Allocs 4,623,066 (± 0.01%) 4,622,687 (± 0.02%) ~ 4,620,003 4,623,784 p=0.443 n=12
Config Time 0.001s 0.001s ~ ~ ~ p=1.000 n=12
Parse Time 0.115s (± 5.89%) 0.113s (± 5.28%) ~ 0.102s 0.135s p=0.619 n=12
Bind Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Check Time 1.050s (± 0.49%) 1.044s (± 0.41%) ~ 1.033s 1.056s p=0.060 n=12
Emit Time 0.135s (±11.97%) 0.130s (±12.31%) ~ 0.091s 0.165s p=0.504 n=12
Total Time 1.351s (± 1.26%) 1.339s (± 1.03%) ~ 1.306s 1.387s p=0.139 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 273,915k (± 0.02%) 273,909k (± 0.04%) ~ 273,417k 274,129k p=0.660 n=12
Memory Allocs 1,615,853 (± 0.02%) 1,615,912 (± 0.01%) ~ 1,615,351 1,616,485 p=0.799 n=12
Config Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Parse Time 0.099s (± 5.64%) 0.100s (± 5.26%) ~ 0.090s 0.112s p=0.744 n=12
Bind Time 0.036s (± 8.36%) 0.036s (± 8.36%) ~ 0.030s 0.045s p=0.898 n=12
Check Time 0.823s (± 0.52%) 0.824s (± 1.07%) ~ 0.811s 0.853s p=0.701 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 0.973s (± 0.80%) 0.974s (± 1.31%) ~ 0.950s 1.014s p=0.899 n=12
vscode - native
Errors 380 380 ~ ~ ~ p=1.000 n=12
Symbols 10,591,714 10,591,714 ~ ~ ~ p=1.000 n=12
Types 3,537,253 3,537,253 ~ ~ ~ p=1.000 n=12
Memory Used 6,870,134k (± 0.02%) 6,868,705k (± 0.01%) ~ 6,866,420k 6,870,554k p=0.052 n=12
Memory Allocs 52,733,074 (± 0.02%) 52,724,484 (± 0.03%) -8,590 (- 0.02%) 52,707,198 52,793,992 p=0.045 n=12
Config Time 0.073s (± 0.37%) 0.073s (± 0.50%) ~ 0.072s 0.074s p=0.496 n=12
Parse Time 1.808s (± 3.58%) 1.775s (± 3.75%) ~ 1.621s 1.926s p=0.340 n=12
Bind Time 0.547s (±20.58%) 0.556s (±20.58%) ~ 0.428s 0.901s p=0.560 n=12
Check Time 13.323s (± 1.27%) 13.280s (± 1.22%) ~ 12.936s 13.584s p=0.799 n=12
Emit Time 4.636s (±10.41%) 5.155s (± 9.81%) ~ 3.916s 5.986s p=0.219 n=12
Total Time 20.467s (± 1.85%) 20.922s (± 1.82%) ~ 19.953s 21.570s p=0.060 n=12
webpack - native
Errors 589 589 ~ ~ ~ p=1.000 n=12
Symbols 1,303,232 1,303,232 ~ ~ ~ p=1.000 n=12
Types 618,887 618,887 ~ ~ ~ p=1.000 n=12
Memory Used 1,005,469k (± 0.02%) 1,005,584k (± 0.01%) ~ 1,005,244k 1,005,927k p=0.551 n=12
Memory Allocs 6,545,098 (± 0.03%) 6,539,428 (± 0.02%) -5,670 (- 0.09%) 6,536,137 6,543,213 p=0.000 n=12
Config Time 0.009s 0.009s ~ ~ ~ p=1.000 n=12
Parse Time 0.282s (± 3.42%) 0.281s (± 2.43%) ~ 0.263s 0.307s p=0.723 n=12
Bind Time 0.085s (±20.63%) 0.084s (±14.27%) ~ 0.063s 0.120s p=0.680 n=12
Check Time 1.991s (± 0.58%) 1.980s (± 0.92%) ~ 1.939s 2.022s p=0.325 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 2.400s (± 0.31%) 2.393s (± 0.62%) ~ 2.341s 2.422s p=0.921 n=12
xstate-main - native
Errors 0 0 ~ ~ ~ p=1.000 n=12
Symbols 1,055,167 1,055,167 ~ ~ ~ p=1.000 n=12
Types 387,939 387,939 ~ ~ ~ p=1.000 n=12
Memory Used 610,319k (± 0.02%) 610,351k (± 0.03%) ~ 609,818k 610,905k p=0.831 n=12
Memory Allocs 4,880,869 (± 0.14%) 4,873,857 (± 0.08%) ~ 4,864,898 4,886,162 p=0.143 n=12
Config Time 0.003s (± 8.64%) 0.003s (±10.34%) ~ 0.002s 0.003s p=1.000 n=12
Parse Time 0.143s (± 2.88%) 0.145s (± 3.16%) ~ 0.134s 0.160s p=0.541 n=12
Bind Time 0.043s (±19.29%) 0.041s (±14.82%) ~ 0.032s 0.061s p=0.853 n=12
Check Time 1.291s (± 0.52%) 1.295s (± 1.01%) ~ 1.272s 1.343s p=0.944 n=12
Emit Time 0.000s 0.000s ~ ~ ~ p=1.000 n=12
Total Time 1.489s (± 0.54%) 1.494s (± 0.78%) ~ 1.474s 1.543s p=0.702 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

@typescript-automation

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg) Here are the results of running the user tests with tsc comparing baseline and pr:

Everything looks good!

@typescript-automation

Copy link
Copy Markdown
Contributor

Anders Hejlsberg (@ahejlsberg) Here are the results of running the top 400 repos with tsc comparing baseline and pr:

Everything looks good!

@ahejlsberg

Copy link
Copy Markdown
Member Author

No measurable effect on perf tests, likely because we don't have react tests which is where it's supposed to help.

Co-authored-by: ahejlsberg <4226954+ahejlsberg@users.noreply.github.com>

@jakebailey Jake Bailey (jakebailey) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Still want this?

@github-project-automation github-project-automation Bot moved this from Not started to Needs merge in PR Backlog Oct 13, 2026
@ahejlsberg
Anders Hejlsberg (ahejlsberg) added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit 6aace8b Oct 14, 2026
29 checks passed
@ahejlsberg
Anders Hejlsberg (ahejlsberg) deleted the cacheSimplifiedConditionalTypes branch October 14, 2026 00:34
@github-project-automation github-project-automation Bot moved this from Needs merge to Done in PR Backlog Oct 14, 2026
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: Done

Development

Successfully merging this pull request may close these issues.

5 participants