Repository navigation
Share complete union and intersection property cache entries - #64789
Jake Bailey (jakebailey) wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Augmented-first synthetic property lookups still retain duplicate entries because independently created symbols fail the pointer-identity check.
1 open finding
What changed in this PR
Optimizes union/intersection property caching to reduce duplicate retained symbols.
Changes:
- Reuses complete non-augmented cache entries.
- Preserves distinct augmented results.
- Adds cache-sharing and function-augmentation tests.
| File | Description |
|---|---|
tsc/internal/checker/checker.go |
Implements cache sharing and cleanup. |
tsc/internal/checker/types.go |
Documents cache semantics. |
tsc/internal/checker/types_test.go |
Tests cache modes and sharing. |
tsc/internal/checker/checker_test.go |
Tests function-property augmentation behavior. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
98420cf to
46ffb18
Compare
847d584 to
1807ffa
Compare
1807ffa to
a6efe11
Compare
46ffb18 to
3b5631d
Compare
a6efe11 to
5b65d47
Compare
3b5631d to
2b8f9af
Compare
2b8f9af to
f7addbf
Compare
5b65d47 to
a4f0e31
Compare
f7addbf to
2a5167f
Compare
a4f0e31 to
9649222
Compare
2a5167f to
51be58b
Compare
9649222 to
33f5302
Compare
51be58b to
f34f38a
Compare
33f5302 to
766660b
Compare
f34f38a to
e59a4dd
Compare
5fea824 to
f7bee08
Compare
e59a4dd to
a15ee39
Compare
3782578 to
779852a
Compare
59c8a48 to
ad1de82
Compare
779852a to
b9fa688
Compare
ad1de82 to
354885c
Compare
b9fa688 to
0aaf90f
Compare
0aaf90f to
1165604
Compare
1165604 to
6aa42dc
Compare
0e30e19 to
8455c76
Compare
6aa42dc to
7e29b1e
Compare
Complete non-augmented properties are valid for augmented lookup, but
copying each result into both caches retains duplicate name tables.
MUI keeps 2,734,919 identical entries this way, nearly doubling its
union/intersection cache storage without adding semantic information.
Preserve independent augmented results and partial-property behavior
while sharing complete entries. A failed lookup needs no empty table.
The MUI census falls from 230242 tables and 5628201 entries to 116635
tables and 2893282 entries; all distinct cached identities remain.
Six fresh-process interleaved single-checker comparisons against the
parent commit, with ordinary GC, save 135.63 MiB of retained MUI heap
(-8.15%) and 132.00 MiB of GC scanning (-9.22%). Total allocated bytes
fall 4.45% and allocation events fall 1.46%. VS Code's corresponding
reductions are small: retained -0.15%, scan -0.17%, allocated -0.16%.
Instruction differences in these single-checker comparisons are
inconclusive; elapsed time is noisy on the shared machine.
Six default-threaded production CLI pairs confirm MUI's reported heap
falls 9.29% and instructions fall 2.60%. VS Code and Webpack have small
heap reductions and inconclusive instruction differences. These are
incremental savings on top of the earlier branch optimizations.
CLI-reported heap is not the forced-GC retained-heap measure above.
MUI uses the CI-pinned source and restored scenario dependencies at
6780195595c12252a130aa5ae5c5bd461229c6b7. VS Code uses
8bf178e1e1c2be3723f14683f7b1e5fdb3f780e4. Webpack uses an isolated
2289141381f2c1c965cb65118fa0ffe2e9e19834 with restored dependencies.
Production diagnostics and all semantic counts match exactly.
Tests cover both query orders, both composite kinds, cache growth and
GC reachability, missing entries, read/write partial flags, differing
mode-specific identities, and real function-property augmentation.
The storage regressions fail before this change.
Single-checker retained heap and allocation measurements:
│ mui-shared-union-before.txt │ mui-shared-union-shared.txt │
│ retained-B │ retained-B vs base │
ExternalMemory-20 1.624Gi ± 0% 1.492Gi ± 0% -8.15% (p=0.002 n=6)
│ mui-shared-union-before.txt │ mui-shared-union-shared.txt │
│ scan-B │ scan-B vs base │
ExternalMemory-20 1.398Gi ± 0% 1.270Gi ± 0% -9.22% (p=0.002 n=6)
│ mui-shared-union-before.txt │ mui-shared-union-shared.txt │
│ B/op │ B/op vs base │
ExternalMemory-20 5.364Gi ± 0% 5.125Gi ± 0% -4.45% (p=0.002 n=6)
│ mui-shared-union-before.txt │ mui-shared-union-shared.txt │
│ allocs/op │ allocs/op vs base │
ExternalMemory-20 25.17M ± 0% 24.80M ± 1% -1.46% (p=0.002 n=6)
│ vscode-shared-union-before.txt │ vscode-shared-union-shared.txt │
│ retained-B │ retained-B vs base │
ExternalMemory-20 2.619Gi ± 0% 2.615Gi ± 0% -0.15% (p=0.002 n=6)
│ vscode-shared-union-before.txt │ vscode-shared-union-shared.txt │
│ scan-B │ scan-B vs base │
ExternalMemory-20 2.291Gi ± 0% 2.287Gi ± 0% -0.17% (p=0.002 n=6)
│ vscode-shared-union-before.txt │ vscode-shared-union-shared.txt │
│ B/op │ B/op vs base │
ExternalMemory-20 3.754Gi ± 0% 3.748Gi ± 0% -0.16% (p=0.002 n=6)
│ vscode-shared-union-before.txt │ vscode-shared-union-shared.txt │
│ allocs/op │ allocs/op vs base │
ExternalMemory-20 23.61M ± 0% 23.59M ± 0% -0.08% (p=0.002 n=6)
Single-checker instructions:
│ mui-shared-union-before.instructions │ mui-shared-union-shared.instructions │
│ instructions/op │ instructions/op vs base │
ExternalInstructions-20 218.9G ± 3% 217.3G ± 2% ~ (p=0.310 n=6)
│ vscode-shared-union-before.instructions │ vscode-shared-union-shared.instructions │
│ instructions/op │ instructions/op vs base │
ExternalInstructions-20 188.8G ± 3% 192.1G ± 2% ~ (p=0.394 n=6)
Default-threaded production CLI:
│ shared-union-cli-before.txt │ shared-union-cli-after.txt │
│ instructions/op │ instructions/op vs base │
mui-20 283.3G ± 1% 275.9G ± 2% -2.60% (p=0.015 n=6)
vscode-20 308.2G ± 7% 293.0G ± 6% ~ (p=0.818 n=6)
webpack-20 51.96G ± 5% 51.82G ± 4% ~ (p=1.000 n=6)
geomean 165.6G 161.2G -2.62%
│ shared-union-cli-before.txt │ shared-union-cli-after.txt │
│ heap-B/op │ heap-B/op vs base │
mui-20 2.059Gi ± 0% 1.868Gi ± 0% -9.29% (p=0.002 n=6)
vscode-20 2.835Gi ± 0% 2.829Gi ± 0% -0.21% (p=0.004 n=6)
webpack-20 666.9Mi ± 0% 663.0Mi ± 0% -0.57% (p=0.002 n=6)
geomean 1.561Gi 1.507Gi -3.45%
│ shared-union-cli-before.txt │ shared-union-cli-after.txt │
│ allocs/op │ allocs/op vs base │
mui-20 29.84M ± 0% 29.55M ± 0% -0.97% (p=0.002 n=6)
vscode-20 36.67M ± 2% 36.64M ± 0% ~ (p=0.132 n=6)
webpack-20 6.235M ± 2% 6.208M ± 0% -0.43% (p=0.002 n=6)
geomean 18.97M 18.87M -0.49%
│ shared-union-cli-before.txt │ shared-union-cli-after.txt │
│ check-sec/op │ check-sec/op vs base │
mui-20 8.986 ± 6% 8.559 ± 4% -4.75% (p=0.026 n=6)
vscode-20 8.345 ± 4% 8.900 ± 10% ~ (p=0.132 n=6)
webpack-20 1.851 ± 8% 1.818 ± 8% ~ (p=0.310 n=6)
geomean 5.178 5.173 -0.08%
7e29b1e to
ee3bc6c
Compare
|
TypeScript Bot (@typescript-bot) perf test this faster |
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| delete(data.propertyCache, name) | ||
| if len(data.propertyCache) == 0 { | ||
| data.propertyCache = nil | ||
| } |
There was a problem hiding this comment.
I'm not that familiar with this code path (I don't entirely know when you need one map but not the other), but I do wonder if you can hit a pathological case where you keep deleting/reallocating maps.
Also, I wonder if you can save anything by having one "steal" a map from the other if the size is just 1.
| assert.Equal(t, defaultClause, defaultReference) | ||
| } | ||
|
|
||
| func TestUnionPropertyFunctionAugmentation(t *testing.T) { |
There was a problem hiding this comment.
What about this test used to fail before?

Complete non-augmented property results are also valid for augmented lookups, but were copied into both caches. MUI keeps 2.7M duplicate entries this way.