Repository navigation
Probe links without creating them on read-only paths - #65021
Jake Bailey (jakebailey) wants to merge 1 commit into
Conversation
Get on a link store allocates and inserts a fresh record when none exists. Many checker paths only read a field from a links record (resolvedSymbol, resolvedType, nameType, target, resolvedSignature) and treat an absent record the same as a zero one, so calling Get there allocates link records, and grows the backing maps and pages, for nodes and symbols that never needed them. Use TryGet on those paths instead, and let the ValueSymbolLinks nameType/containingType accessors accept a nil receiver so the common "copy the name type from the source symbol" pattern can probe without allocating. Co-authored-by: Steven Chong <25894545+teamchong@users.noreply.github.com>
|
TypeScript Bot (@typescript-bot) perf test this faster |
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are reported for the changes that reduce unnecessary checker-link allocations.
No open issues 🎉
What changed in this PR
This PR reduces unnecessary checker allocations by probing existing link records on read-only paths instead of creating empty records.
Changes:
- Replace allocating
Getcalls withTryGetfor read-only symbol, type, and signature lookups. - Make name-type and containing-type accessors safe for nil link records.
- Reuse lookup helpers to preserve absent-record behavior without allocation.
| File | Description |
|---|---|
tsc/internal/checker/types.go |
Allow nil receivers in name-type and containing-type accessors. |
tsc/internal/checker/inference.go |
Copy reverse-mapped property name types without allocating source links. |
tsc/internal/checker/checker.go |
Use non-allocating probes across read-only checker paths. |
Review effort: Balanced
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ryan Cavanaugh (RyanCavanaugh)
left a comment
There was a problem hiding this comment.
Reviewed at 61bf64c. Absent-link reads preserve the previous zero-record semantics, including name-type copies and guarded symbol/target/signature reads; allocating writes remain intact. Checker tests and targeted spread, reverse-mapping, private-member, and CommonJS compiler baselines passed. No blocking issue found.
Get on a link store allocates and inserts a fresh record when none exists. Many checker paths only read a field from a links record (resolvedSymbol, resolvedType, nameType, target, resolvedSignature) and treat an absent record the same as a zero one, so calling Get there allocates link records, and grows the backing maps and pages, for nodes and symbols that never needed them.
Use TryGet on those paths instead, and let the ValueSymbolLinks nameType/containingType accessors accept a nil receiver so the common "copy the name type from the source symbol" pattern can probe without allocating.
Thanks Steven (@teamchong) for finding this!