-
Notifications
You must be signed in to change notification settings - Fork 192
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
feat: single-linked list for resolver stack #443
base: main
Are you sure you want to change the base?
Conversation
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.
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
lib/Resolver.js:748
- [nitpick] The error message string might be unclear. Consider updating it to provide more context about the recursion.
"Recursion in resolving\nStack:" + formatStack(stackEntry)
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.
@dmichon-msft Great work!
I would like to see this improvement for webpack,
Note that this is a breaking change that will require an update to webpack's ResolverCachePlugin.
Which places we need to rewrite?
Maybe we can implement this under an option (or internal value for resolver like resolver.optimizaStack = true
)? So we will mark old logic as deprecated (and put todo for removing it in the next major release), then rewrite some things in webpack and use it
What do you think?
The only change to ResolverCachePlugin (which does still function without the change, it just does unnecessary work), is the removal of the We could fork the logic here, though it only impacts plugins that inspect or instantiate |
Can you explain? I would prefer a solution that will allow to avoid critical changes now and get perf improvements right now, That's is why I thought about a new option, my concern is also related to the fact that we don’t know how other developers use our code, we have very many downloads every week. |
I have some thoughts on how we can make this be a resolver option and keep the public API almost the same even when enabled (e.g. make |
@dmichon-msft Will be great to look at this ⭐ Also how you do profiling/benches, can you provide a code? I think will be great to add it in our repo for future improvement and checks (if you have time feel free to send a separate PR with it) |
Improve performance of
doResolve
by representing the resolver stack via a singly-linked list instead of aSet<string>
. Profiling indicated that a significant amount of time was spent cloningresolveContext.stack
duringdoResolve
; replacing with a singly-linked list reduces the total memory footprint and makes adding a new entry be O(1) in both time and memory, in exchange for making the circularity check be O(n).Additionally, this avoids allocating strings for the formatted stack until required when logging it.
Local profiling showed a reduction from 2400ms of self time in
doResolve
to 88ms of self time plus 73ms for the cost ofhasStackEntry
, a net reduction of 2239ms.Measured on NodeJS 18.19.1.
Note that this is a breaking change that will require an update to webpack's
ResolverCachePlugin
.