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
perf(core): check files before interacting with them #13090
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/45558/ |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 429e2e6:
|
I think in the past we already used |
That's good to know. I was worried that this was there for a real reason; couldn't see anything in the git history. |
That's a good change imo. If someone is passing a file to Babel and Babel cannot read it, it's better to throw an explicit error than to silently not do what the user is asking Babel to do. |
67b6e93
to
6edecd5
Compare
adc5b75
to
eebb473
Compare
eebb473
to
429e2e6
Compare
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.
Thanks!
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.
For reference, both fs.accessSync
and fs.existsSync
call binding.access
under the hodd:
https://github.com/nodejs/node/blob/fa6d084dcbe1bf5e1b7d9aee2e02758b84c0aade/lib/fs.js#L230
https://github.com/nodejs/node/blob/fa6d084dcbe1bf5e1b7d9aee2e02758b84c0aade/lib/fs.js#L268
but existsSync
does not handle the thrown uvException
, instead it just checks the errno
so it is faster than accessSync
.
What this does
babel
is relevantly slower thants-jest
at transpiling our codebase, after caching. A profiler suggests these file APIs are slow. UseexistsSync
instead, which is quite a bit faster.This is a problem I've seen before, and potentially raised as a bug here before, but am currently unable to find. 🤷
Benchmarks
require('./app')
(inside jest, which has other overheads) goes from 6.5s±0.5s to 5.0s±0.1s, which is >20% faster. For reference,ts-jest
's cache can do the same operation in 4.3s±0.1s.Node 14, Ubuntu, linux 5.8, desktop i7-8700, nvme, btrfs.
@babel/preset-env
,@babel/preset-typescript
. Around 2,000 source files, around 44,000 files inside node_modules appear to be referenced, according tostrace -ff -yy -estatx,openat node =jest --runInBand require-stuff
.Semantic change
This is technically a semantic change, if you previously had files that you couldn't read, you will now see an error when trying to read them (after this function), instead of them being silently ignored. I think this is better behaviour. If we don't agree, maybe we could check
existsSync
thenaccessSync
.Profiler output
I believe the
uvException
is explaining that it's expensive to throw and catch and exception, even if you ignore the caught value.