bolt icon indicating copy to clipboard operation
bolt copied to clipboard

Improve performance of symlinking

Open jamiebuilds opened this issue 7 years ago • 2 comments

Right now symlinking includes a lot of intensive file operations:

https://github.com/boltpkg/bolt/blob/d2ca298ed057b4b9c2f05fe4e6d45f645ddc04e2/src/utils/fs.js#L48-L109

Basically every single symlink() we create we do the following operations:

await mkdirp(dest)
await lstat(dest)
await rimraf(dest)
await symlink(dest, target)

This is terrible for performance, with 500 Bolt packages needing just 10 symlinks each we have 5,000 symlinks which turns into 20,000 file operations not including the overhead of Node/libuv and internal operations of mkdirp/rimraf/etc

As part of running the install process we aggregate all of the symlinks we need to create, so I think we could make this much more optimized by manually writing out only the operations we need.

We might be able to optimize it even more by doing readdir()'s with withFileTypes and either assuming the symlinks are good or using readlink() to verify them cheaply

jamiebuilds avatar Oct 09 '18 01:10 jamiebuilds

Sweet. Just so I understand the idea here is to only link files that aren't already there essentially?

One other thing we could consider, we currently symlink all root bin files into all packages. I think the idea was to go back and only do the ones that were required? This might be a little problematic (or maybe good depending on how you look at it) as it'll probably show a lot of places that we use binaries without declaring their dev deps...

lukebatchelor avatar Oct 09 '18 21:10 lukebatchelor

Technically the symlinks we're adding in Bolt are 100% unnecessary, I only wanted them for the potential future of having a .bolt directory with virtual installs. But I'm not sure we're going to go down that route anymore.

jamiebuilds avatar Oct 09 '18 21:10 jamiebuilds