-
Notifications
You must be signed in to change notification settings - Fork 12.9k
addTypeToIntersection performance improvement #32388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@typescript-bot perf test |
Maybe I can run it @typescript-bot perf test |
Heya @orta, I've started to run the perf test suite on this PR at 8871463. You can monitor the build here. It should now contribute to this PR's status checks. Update: The results are in! |
@orta Here they are:Comparison Report - master..32388
System
Hosts
Scenarios
|
Thanks @orta. Do I need to ping someone to review the PR? |
Nah, someone who knows the are of the codebase better than I will come along and review - you're in a good spot. |
const flags = type.flags; | ||
if (flags & TypeFlags.Intersection) { | ||
return addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types); | ||
} | ||
if (isEmptyAnonymousObjectType(type)) { | ||
if (!(includes & TypeFlags.IncludesEmptyObject)) { | ||
includes |= TypeFlags.IncludesEmptyObject; | ||
typeSet.push(type); | ||
typeSet.set(type.id.toString(), type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use the getTypeId
function here, since IIRC, type IDs are lazily assigned.
Thanks @weswigham. I've made the change. BTW, the implementation of |
🤦♂ I'm thinking of |
@weswigham I'm not sure I understand - what do you mean by deferred? Also, Should I revert my latest change? |
Yeah, just revert the original change I asked for - I was incorrect. |
@weswigham done. |
Thanks - the perf results are promising on our general suites (with results ranging from neutral to slightly positive), but I'm going to hold off merging for a second because I want to write up a microbenchmark where we can definitively see the change on (because I was once told in the past that this would be a premature optimization and that the memory pressure of swapping between an array and a map would probably make it a wash). I'll put one together shortly... |
Ooof, nice - at a glance (haven't done the math/many iterations/clean machine), but on my microbenchmark with a 10000 element intersection (of unique but structurally identical object types), check time is dropped in half with this change. Nice. |
Yep, the numbers look real good in microbenchmarks. On master, I've collected these timings from my laptop over 50 iterations per datum (where the datum is the number of intersection elements in a simple
(a 10x increase in size is a 100x increase in time after a point) While with this simple fix:
With 1000 or fewer elements, the timings are similar, but above that... on |
Fixes #29289
Changes the type of
types
argument fromType[]
toMap<Type>
so that membership checking can be done in O(1) instead of O(n).