grunt-contrib-copy icon indicating copy to clipboard operation
grunt-contrib-copy copied to clipboard

Slow on windows

Open greggman opened this issue 4 years ago • 2 comments

It takes > 2 minutes for it to copy the files I need it to copy. Compared to cp -Recurse src dst which takes 24 seconds. There are ~8k files but still, 29 second vs 130 seconds, something is wrong.

As a hack I went into lib/copy.js and changed

grunt.verbose.writeln('Copying ' + chalk.cyan(src) + ' -> ' + chalk.cyan(dest));
grunt.file.copy(src, dest, copyOptions);
syncTimestamp(src, dest);
if (options.mode !== false) {
  fs.chmodSync(dest, (options.mode === true) ? fs.lstatSync(src).mode : options.mode);
}

to

grunt.verbose.writeln('Copying ' + chalk.cyan(src) + ' -> ' + chalk.cyan(dest));
try {
  fs.mkdirSync(path.dirname(dest), {recursive: true});
} catch(e) {
}
fs.copyFileSync(src, dest);

And it went down to 20 seconds. Maybe if the options are all ok it could do this instead? Note: fs.copyFile already copies the timestamp and the modes

greggman avatar May 30 '20 12:05 greggman

so fyi here's 2 runs before the change (the 2nd being hot)

❯ Measure-Command { npx grunt copy }

Days              : 0
Hours             : 0
Minutes           : 3
Seconds           : 47
Milliseconds      : 599
Ticks             : 2275995177
TotalDays         : 0.00263425367708333
TotalHours        : 0.06322208825
TotalMinutes      : 3.793325295
TotalSeconds      : 227.5995177
TotalMilliseconds : 227599.5177


[18:44]
❯ Measure-Command { npx grunt copy }

Days              : 0
Hours             : 0
Minutes           : 2
Seconds           : 16
Milliseconds      : 287
Ticks             : 1362877621
TotalDays         : 0.00157740465393519
TotalHours        : 0.0378577116944444
TotalMinutes      : 2.27146270166667
TotalSeconds      : 136.2877621
TotalMilliseconds : 136287.7621

and here's 2 runs after

❯ npm install --save-dev greggman/grunt-contrib-copy#8x-faster-copy
+ [email protected]
updated 2 packages and audited 618 packages in 13.66s
❯ Measure-Command { npx grunt copy }

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 13
Milliseconds      : 705
Ticks             : 137053930
TotalDays         : 0.000158627233796296
TotalHours        : 0.00380705361111111
TotalMinutes      : 0.228423216666667
TotalSeconds      : 13.705393
TotalMilliseconds : 13705.393


❯ Measure-Command { npx grunt copy }

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 13
Milliseconds      : 939
Ticks             : 139395238
TotalDays         : 0.000161337081018519
TotalHours        : 0.00387208994444444
TotalMinutes      : 0.232325396666667
TotalSeconds      : 13.9395238
TotalMilliseconds : 13939.5238

Of course you have to put options: { mode: true, timestamp: true} in the grunt file.

I also figured out the reason. fs.copyFile(Sync) calls into the OS to copy the file where as grunt.file.copy reads bytes and writes bytes. This ends up triggering the windows built in virus scanner

Taskmgr_5oYbxnRUa6

With the fix that virus scanning disappears. I guess because the OS knows it's making a copy of a previously scanned file where as it can't know that with grunt.file.copy

greggman avatar Jun 06 '20 10:06 greggman

I also figured out the reason. fs.copyFile(Sync) calls into the OS to copy the file where as grunt.file.copy reads bytes and writes bytes. This ends up triggering the windows built in virus scanner

Ah :(

vladikoff avatar Jun 08 '20 14:06 vladikoff