Skip to content
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

FS caching improvements #375

Merged
merged 2 commits into from Feb 12, 2017
Merged

FS caching improvements #375

merged 2 commits into from Feb 12, 2017

Conversation

akx
Copy link
Contributor

@akx akx commented Feb 10, 2017

While tracking down the reason for some build slowness with --trace-sync-io, I found a couple file system hotspots that could use some caching.

  • When using cacheDirectory=true, findCacheDir is repeatedly called, and it does some synchronous calls under the hood. However findCacheDir is more or less a pure function, so it's probably safe to call it once during process lifetime.
  • resolve-rc has some caches for single exists and read operations, but there's still some more time that can be shaved off by simply memoizing the entire resolve-rc function.

These should not be breaking changes, unless .babelrcfiles are created in intermediate directories during process lifetime, which sounds very unlikely.

When using `cacheDirectory=true`, the `findCacheDir` module
is repeatedly called, and it does some synchronous filesystem
calls under the hood. However, since `findCacheDir` is more
or less a pure function, it's probably safe to call it only
once during process lifetime.
@codecov-io
Copy link

codecov-io commented Feb 10, 2017

Codecov Report

Merging #375 into master will increase coverage by 0.82%.
The diff coverage is 88.88%.

@@            Coverage Diff             @@
##           master     #375      +/-   ##
==========================================
+ Coverage   81.04%   81.87%   +0.82%     
==========================================
  Files           6        6              
  Lines         153      160       +7     
  Branches       33       35       +2     
==========================================
+ Hits          124      131       +7     
  Misses         13       13              
  Partials       16       16
Impacted Files Coverage Δ
src/resolve-rc.js 94.11% <100%> (+1.8%)
src/fs-cache.js 72.54% <75%> (+1.71%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0b19a6d...9b63ffb. Read the comment docs.

@akx akx changed the title Caches FS caching improvements Feb 10, 2017

return find(loc, rel);
return (cache[cacheKey] = find(loc, rel));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For readability here can you use a template string and reverse the logic?

if (!cacheKey in cache) {
   cache[cacheKey] = ...
}

return cache[cacheKey];

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done deal. I wasn't sure whether template strings were allowed by the local code style. :)

@danez
Copy link
Member

danez commented Feb 12, 2017

Thanks, that looks all awesome. Did you check if the build gets faster with this?

@akx
Copy link
Contributor Author

akx commented Feb 12, 2017

I measured things a little (somewhat unscientifically, of course, since this is on my MBP and there's other IO and processing noise). The "babel-core" patch mentioned is babel/babel#5292 .

The TL;DR is "yes, it does have an effect 😸 "

Performance measurements

for i in (seq 1 5); time node --trace-sync-io ./node_modules/.bin/webpack 2>> perf-SETUP.txt; end
# repeat the above for different setups
grep "real " perf-*.txt | perl -pe 's/^(.+?):\s+([0-9.]+).+$/\1=\2/' | awk -F= '{t[$1] += $2;}END{for(name in t)print name, t[name];}'
Setup Total Time Effect against stock
All Stock 108.58 0%
Patched babel-loader 102.53 -5.9%
Patched babel-loader and babel-core 100.72 -7.8%

Sync IO traces

Output summarized by https://github.com/akx/summarize-sync-io

All stock

###############      11870 fs.existsSync by babel-loader/lib/utils/exists.js:null
###########....       7710 fs.fstatSync by babel-core/lib/transformation/file/options/build-config-chain.js:addConfig
###########....       7710 fs.readSync by babel-core/lib/transformation/file/options/build-config-chain.js:addConfig
###########....       7710 fs.openSync by babel-core/lib/transformation/file/options/build-config-chain.js:addConfig
###............       1315 fs.existsSync by babel-core/lib/transformation/file/options/build-config-chain.js:exists
#..............         70 fs.lstatSync by babel-core/lib/helpers/resolve.js:exports.default
#..............         10 fs.readSync by babel-loader/lib/utils/read.js:null
#..............         10 fs.openSync by babel-loader/lib/utils/read.js:null
#..............         10 fs.fstatSync by babel-loader/lib/utils/read.js:null
#..............          5 fs.mkdirSync by mkdirp/index.js:sync
#..............          5 fs.statSync by mkdirp/index.js:sync
#..............          5 fs.openSync by webpack-bundle-tracker/index.js:Plugin.writeOutput

Patched babel-loader

###############       7710 fs.fstatSync by babel-core/lib/transformation/file/options/build-config-chain.js:addConfig
###############       7710 fs.readSync by babel-core/lib/transformation/file/options/build-config-chain.js:addConfig
###############       7710 fs.openSync by babel-core/lib/transformation/file/options/build-config-chain.js:addConfig
####...........       1315 fs.existsSync by babel-core/lib/transformation/file/options/build-config-chain.js:exists
###............       1025 fs.existsSync by babel-loader/lib/utils/exists.js:null
#..............         70 fs.lstatSync by babel-core/lib/helpers/resolve.js:exports.default
#..............         10 fs.readSync by babel-loader/lib/utils/read.js:null
#..............         10 fs.openSync by babel-loader/lib/utils/read.js:null
#..............         10 fs.fstatSync by babel-loader/lib/utils/read.js:null
#..............          5 fs.mkdirSync by mkdirp/index.js:sync
#..............          5 fs.statSync by mkdirp/index.js:sync
#..............          5 fs.openSync by webpack-bundle-tracker/index.js:Plugin.writeOutput

Patched babel-loader and babel-core

###############       1315 fs.existsSync by babel-core/lib/transformation/file/options/build-config-chain.js:exists
#############..       1025 fs.existsSync by babel-loader/lib/utils/exists.js:null
###............        160 fs.readSync by babel-core/lib/transformation/file/options/build-config-chain.js:addConfig
###............        160 fs.openSync by babel-core/lib/transformation/file/options/build-config-chain.js:addConfig
###............        160 fs.fstatSync by babel-core/lib/transformation/file/options/build-config-chain.js:addConfig
##.............         70 fs.lstatSync by babel-core/lib/helpers/resolve.js:exports.default
#..............         10 fs.readSync by babel-loader/lib/utils/read.js:null
#..............         10 fs.openSync by babel-loader/lib/utils/read.js:null
#..............         10 fs.fstatSync by babel-loader/lib/utils/read.js:null
#..............          5 fs.mkdirSync by mkdirp/index.js:sync
#..............          5 fs.statSync by mkdirp/index.js:sync
#..............          5 fs.openSync by webpack-bundle-tracker/index.js:Plugin.writeOutput

@danez
Copy link
Member

danez commented Feb 12, 2017

Thank you

@danez danez merged commit 4b3bafa into babel:master Feb 12, 2017
danez pushed a commit that referenced this pull request Feb 12, 2017
* Instantiate default cache directory lazily, and only once

When using `cacheDirectory=true`, the `findCacheDir` module
is repeatedly called, and it does some synchronous filesystem
calls under the hood. However, since `findCacheDir` is more
or less a pure function, it's probably safe to call it only
once during process lifetime.

* Cache resolve-rc results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants