-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Don't cache child lists for tokens #58233
Conversation
…all child-lists as readonly arrays.
@typescript-bot perf test this |
Looks like you're introducing a change to the public API surface area. If this includes breaking changes, please document them on our wiki's API Breaking Changes page. Also, please make sure @DanielRosenwasser and @RyanCavanaugh are aware of the changes, just as a heads up. |
I guess an alternative path would be to have |
src/compiler/factory/nodeChildren.ts
Outdated
const nodeChildren = new WeakMap<Node, Node[] | undefined>(); | ||
const nodeChildren = new WeakMap<Node, readonly Node[] | undefined>(); | ||
|
||
const emptyChildren: readonly Node[] = Object.freeze([]); |
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.
Why not use emptyArray
?
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.
Confusingly, services defines its own mutable empty array (and none of them actually guard against modification)
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.
Oh, this isn't even in services, yeah, emptyArray would be nice. (I used to have a PR that froze it but it didn't really seem to matter)
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.
From the description:
If we want, we can probably just use the internal
emptyArray
, but I don't think we've ever frozen that one.
Happy to switch over to that too, but Jake mentioned that he didn't want to make that change since getChildren()
always was declared as a mutable array. Freezing this array (for runtime safety) and propagating the change (for static verification) helped validate that it's unlikely we mutate these arrays.
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.
Does freezing emptyArray
affect our perf at all? If not, I'd just do that and use emptyArray
.
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.
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.
it sure looks like freezing is bad: #58240 (comment)
@typescript-bot test top400 |
@DanielRosenwasser Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
tsserverComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
startupComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
@DanielRosenwasser Here are the results of running the top 400 repos comparing Everything looks good! |
@typescript-bot perf test this |
getNodeChildren
@DanielRosenwasser Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
tsserverComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
startupComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
It turns out that we always made this optimization - the only difference with this PR is that now
I don't know if there is a difference practically between |
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.
Seems reasonable to me
They're equivalent in behavior, but But yes, better to not stick that empty array into the weak map over and over. |
This PR always returns a shared frozen array from
getNodeChildren
when given a token (e.g. an identifier or any other keyword, punctuation, etc.). It also marks all child-lists asreadonly Node[]
instead of justNode[]
.If we want, we can probably just use the internal
emptyArray
, but I don't think we've ever frozen that one.