Repository navigation
Avoid closure and slice allocations in core helpers and type filtering - #65041
Open
Jake Bailey (jakebailey) wants to merge 4 commits into
Open
Jake Bailey (jakebailey) wants to merge 4 commits into
Jake Bailey (jakebailey) wants to merge 4 commits into
Conversation
When Filter, FilterIndex, or Deduplicate find the first element to drop, they cloned the kept prefix and then grew the result with append. The clone is sized to the prefix only, so any further kept elements trigger one or more reallocations and copies, and the leftover capacity of each abandoned backing array is wasted. The number of remaining elements bounds the result, so allocate that capacity once. For Filter, first skip past any further removed elements: this makes the bound tighter, and when nothing is kept the result is a zero-capacity slice that needs no allocation at all. The case where nothing is removed still returns the input unchanged. Co-authored-by: Steven Chong <[email protected]>
filterType used core.Filter to build the filtered constituent lists of a union and its origin. Those lists are only inputs to union construction, which interns the result and copies the list only when a new union type has to be created; often an existing union is found and the freshly allocated lists are garbage immediately. Scan for the first removed constituent before doing any work, and build both lists in borrowed temporary type sets instead of on the heap. The origin filter also no longer needs a closure wrapping the predicate. removeType on a two-constituent union (such as `T | undefined`, which is very common) now compares the two constituents directly instead of binary searching with CompareTypes. Co-authored-by: Steven Chong <[email protected]>
containsMissingType was stored as a func-valued checker field built from a closure at checker creation. Calls through the field are indirect and cannot be inlined, and the field costs a word per checker. Nothing needs it to be a value, so make it an ordinary method. Co-authored-by: Steven Chong <[email protected]>
structuredTypeRelatedToWorker is one of the hottest functions in the checker, but it built the relateVariances closure on every call, even though only the generic type reference and alias paths use it. The closure also captured and assigned several of the function's locals, which forces them to live in memory for the whole body instead of in registers. Make it a method that receives the state it updates explicitly. The closure also assigned the outer result, but on every path where the caller continues that value is TernaryFalse, which result already holds there. Co-authored-by: Steven Chong <[email protected]>
Member
Author
|
TypeScript Bot (@typescript-bot) perf test this faster |
Contributor
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are blocking the allocation-overhead optimizations.
No open issues 🎉
What changed in this PR
This PR targets allocation overhead in the native TypeScript compiler’s core slice helpers and type checker.
Changes:
- Preallocate result capacity in filtering and deduplication helpers.
- Replace captured closures with methods for variance comparison and missing-type checks.
- Reuse temporary storage for union filtering and add a two-member union removal fast path.
| File | Description |
|---|---|
tsc/internal/core/core.go |
Preallocates filtering and deduplication results to avoid repeated slice growth. |
tsc/internal/checker/relater.go |
Extracts variance comparison from a closure into a method. |
tsc/internal/checker/checker.go |
Reuses filtering storage, converts a closure to a method, and optimizes two-member union removal. |
Review effort: Balanced
Contributor
|
Jake Bailey (@jakebailey) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thanks Steven (@teamchong) for finding these!