-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Build a high-performance version of resolve
#2925
Comments
Update (re #3597) - I added a super simple memoization to |
Since HasteFS isn't available to the public, are there any other plans to improve the performance of |
HasteFS is open source and part of jest-haste-map, it's simply a simple virtual filesystem that contains a list of all files in a project. |
@cpojer Is there a guide to setting this up? |
It's all automatic, jest-haste-map is used throughout Jest. |
Here is the workaround I use in my setup to speedup https://gist.github.com/urish/1a106ad6d1dbfcf77f5f744ae854fd6a For me, this small change reduces the test suite run time from about 21 to 14 seconds when using workers, and from about 27 seconds to 16.5 seconds when using |
I've given this an initial look over in tvald-contrib/jest@feature/haste-resolve. I think the biggest hurdle is that I'll continue working on this, however, as there are several obvious optimizations for |
@tvald woah, awesome! I'm happy to review pull requests. If your first change is simply to integrate all of resolve's code into jest-resolve, then we can take it from there. Generally, the smaller and more incremental your pull requests are, the more likely it is that we'll merge them quickly :) I share the hasteFS concern. If watchman can return directories I'm not opposed to add directories to the hasteFS data structure. |
Working on the initial PR over at #4315. Once that's in, I'll submit a tiny follow-up PR with memoization that improves resolve performance by orders of magnitude. HasteFS might not even be necessary, although it would certainly improve performance even further. |
Memoized PR is at #4323. Also, noting in this thread that @cpojer requested the following:
|
Moving discussion back from #4323:
|
There are some smaller optimizations which don't involve memoization that I'll open a PR for. Note that
Most resolution does seem to occur via an instance of Unfortunately, I don't think that alone will provide enough of a performance boost for Jest to be usable with our codebase. |
New PR at #4325, with cleaned up code and the slight optimization of testing whether a directory exists before attempting to resolve (potentially 10+) paths within that directory. |
After some profiling, it looks like memoization-per-test doesn't offer a significant improvement. I'll submit a PR anyways, since HasteFS support should be quite similar to memoization. Performance-wise, we saw our full test suite drop from ~230s to ~220s (-10s / -4%). |
By memoizing the default resolver, we're seeing a 3x speed boost in our tests. More details here: #4323 (comment) |
@tvald you wouldn't by any chance be open to working more on this? 😀 Jest is MIT now |
Looking at this now in 2020, I think we should reverse course and go back to using the
|
Yeah that makes sense. The main intent of this issue was to build a really fast resolver, I don't care as much about the implementation details. Resolution is one of the hottest paths during a test run, so a 20% improvement for resolution may result in a 10-20% improvement in overall test runtime. |
This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days. |
In general, the entire Related, we've added caches for most file operations, so some optimization has landed already. |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
In Jest, we use
jest-resolve
to resolve modules. However, it shells out to two other dependencies,resolve
andbrowser-resolve
.resolve
hasn't been maintained as much as I'd like, we have a hacky workaround inside ofjest-resolve
and we actually have knowledge of the entire filesystem (minus directories) in "HasteFS" (currently not passed to jest-resolve but that can be changed as the places it is created already passes a "ModuleMap" which is also coming fromjest-haste-map
).The idea is to take the synchronous part of
resolve
and put it inside ofjest-resolve
. Then rewrite it and fine-tune it for performance (cc @trueadm) and use "HasteFS" to optimize the best case scenario (you can usejest-file-exists
which is O(1) in the best case and fs.stat in the worst case).The end state should be for Jest not to depend on
resolve
any longer. We do not need the asynchronous part of resolve.Call to resolve: https://github.com/cpojer/jest/blob/master/packages/jest-resolve/src/index.js#L84
See: https://github.com/substack/node-resolve/blob/master/lib/sync.js
Follow-up: We should also aim at replacing browser-resolve and making it configurable so that our resolution algorithm can look at any field in package.json to re-route resolution to a module. This can be done in a follow-up, because this is already a big task :)
browser-resolve: https://github.com/defunctzombie/node-browser-resolve
cc @DmitriiAbramov @wanderley
The text was updated successfully, but these errors were encountered: