-
Notifications
You must be signed in to change notification settings - Fork 55
Performance: Parallelize recursive directory copying #2409
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
base: trunk
Are you sure you want to change the base?
Conversation
b56e9a9 to
05becb2
Compare
fredrikekelund
left a comment
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.
Clever solution, @ivan-ottinger 👍 We should add p-limit@^3.1.0 to our package.json file before landing this PR, but I'll still approve it now to unblock you.
I went on a tangent exploring how we might use the limit.map API which is available in more recent version of p-limit, but ended up finding that it actually breaks in several ways (see my review comment).
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.
I was going to suggest we do something like my suggestion below, but apparently, there are several issues with this solution (see bottom):
const recursiveCopyLimiter = pLimit( 100 );
export async function recursiveCopyDirectory(
source: string,
destination: string
): Promise< void > {
await fsPromises.mkdir( destination, { recursive: true } );
const entries = await fsPromises.readdir( source, { withFileTypes: true } );
await recursiveCopyLimiter.map( entries, async ( entry ) => {
const sourcePath = path.join( source, entry.name );
const destinationPath = path.join( destination, entry.name );
if ( entry.isDirectory() ) {
await recursiveCopyDirectory( sourcePath, destinationPath );
} else if ( entry.isFile() ) {
await fsPromises.copyFile( sourcePath, destinationPath );
}
} );
}- We should add
p-limitto package.json, but something with how the more recent versions use ESM doesn't play nicely with our Vite config, and I end up getting errors like "pLimit is not a function" when testing my suggestion. Frustrating… - I thought that moving the limiter definition outside the function to control the overall parallelism was smart, but that won't work (see Recursive use of p-limit may cause silent task loss when inner tasks depend on limited concurrency sindresorhus/p-limit#91)
The solution to these problems, as I see it, is to leave the code as is and add p-limit@^3.1.0 to our package.json file.
|
Out of curiosity, did you compare performance between this approach and using the We're using that API elsewhere in our codebase. Might be nice to standardize on the most performant approach. |
c04a487 to
f185857
Compare
📊 Performance Test ResultsComparing d13094b vs trunk site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change |
Good point! I have compared all three approaches on macOS. Using current → I have made the change in fbb9352. |
f6c54ec to
d13094b
Compare
fredrikekelund
left a comment
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.
LGTM 👍 Thanks for taking another look and improving consistency.
gcsecsey
left a comment
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 @ivan-ottinger for improving the performance! The changes LGTM, and I found no regressions when testing both on Mac and Windows. 👍
Related issues
Proposed Changes
Compared to the current
trunkI have measured about 16% speed-up of the site creation process on macOS (about 1.2 s saving). On Windows the percentage is smaller (about 6%) - as the overall site creation process takes longer there.Testing Instructions
npm install && npm start.Pre-merge Checklist