chokidar: Network drives on win32: 24x slower
I’m trying to use chokidar on Windows Shares and finding it’s extremely slow on the initial scan. For a relatively small tree of files (183 entries of directories and files)
tree /F path/to/share/folder
takes 3.5 seconds
dir /S /A /B path/to/share/folder
which gets most of the same stat data takes about the same amount of time where as
chokidar path/to/share/folder -p --verbose --initial -c "echo"
Takes 80 seconds until chokidar emits ‘ready’ or about 24x as long
Those same shares on Mac (same NAS, also smb), same options is fast (3.5 seconds)
I’m wondering if there is some way to speed up the initial scan?
Just doing my own recursive fs.readdir with an fs.stat on every file is only (9.5 seconds) or 8x faster (tho still 3x slower than dir/tree)
To see the ready event here is my chokidar test
const fs = require('fs');
const path = require('path');
const chokidar = require('chokidar');
const watcher = chokidar.watch(process.argv[2], {
usePolling: true,
alwaysStat: true,
});
watcher.on('add', (fn, stats) => { console.log(fn, "file", stats.size); });
watcher.on('addDir', (fn, status) => { console.log(fn, "dir"); });
watcher.on('ready', () => {
console.log("---done---");
watcher.close();
});
and here’s my readdir test
const fs = require('fs');
const path = require('path');
function readDir(dirname) {
fs.readdir(dirname, (err, fileNames) => {
fileNames.forEach((filename) => {
const fullpath = path.join(dirname, filename);
fs.stat(fullpath, (err, stats) => {
console.log(fullpath, stats.isDirectory() ? "dir" : "file", stats.size);
if (stats.isDirectory()) {
readDir(fullpath);
}
});
});
});
}
readDir(process.argv[2]);
And here’s what the test tree looks like. Note: this is not a typical folder I’m watching it was just something on my NAS that was a reasonable size to test. A typical folder is MUCH deeper with 1000s of files and chokidar takes many many minutes until it gets done with it’s initial scan.
Z:\SRC
├───bin
│ │ .gitignore
│ │ backup-stuff.py
│ │ chup.sh
│ │ cyg-wrapper.sh
│ │ e
│ │ e.bat
│ │ encode-html-entities.py
│ │ publish-gh-pages
│ │ s
│ │ setup-ssh-agent
│ │ start-chrome-chromium.bat
│ │ start-chrome-google.bat
│ │ start-chrome-home.bat
│ │ start-chrome.bat
│ │ update-web
│ │ v
│ │
│ ├───.git
│ │ │ config
│ │ │ description
│ │ │ HEAD
│ │ │ index
│ │ │ packed-refs
│ │ │
│ │ ├───branches
│ │ ├───hooks
│ │ │ applypatch-msg.sample
│ │ │ commit-msg.sample
│ │ │ post-update.sample
│ │ │ pre-applypatch.sample
│ │ │ pre-commit.sample
│ │ │ pre-push.sample
│ │ │ pre-rebase.sample
│ │ │ pre-receive.sample
│ │ │ prepare-commit-msg.sample
│ │ │ update.sample
│ │ │
│ │ ├───info
│ │ │ exclude
│ │ │
│ │ ├───logs
│ │ │ │ HEAD
│ │ │ │
│ │ │ └───refs
│ │ │ ├───heads
│ │ │ │ master
│ │ │ │
│ │ │ └───remotes
│ │ │ └───origin
│ │ │ HEAD
│ │ │
│ │ ├───objects
│ │ │ ├───03
│ │ │ │ 363d47c3fea3d8c0ec2355f07d901d0c440213
│ │ │ │
│ │ │ ├───07
│ │ │ │ 1bd8a26f7e3617f2de32c357895bb5ccfaa085
│ │ │ │
│ │ │ ├───0c
│ │ │ │ 5eeed0d70908f44475750d2549168928996b2f
│ │ │ │
│ │ │ ├───11
│ │ │ │ 558cfb280cac51bc9cb1788f2735a57468a5c9
│ │ │ │
│ │ │ ├───1a
│ │ │ │ 32d2f604ab8fc183b004e8f6fcf18c75f05c47
│ │ │ │
│ │ │ ├───21
│ │ │ │ 8bb4889192ef127c7ff066b37dd3af493530ed
│ │ │ │
│ │ │ ├───27
│ │ │ │ 84fa693f18a9ad2be3abd520d5ebc740209b66
│ │ │ │
│ │ │ ├───2d
│ │ │ │ b323901c6ee0886260b0bcfb0481fecd60f5f1
│ │ │ │
│ │ │ ├───30
│ │ │ │ b9317a0548d6b3d289d5fe9cc7fd62bdf55b06
│ │ │ │
│ │ │ ├───32
│ │ │ │ def067fb17c7c3e0b865d234dc4552adf543bb
│ │ │ │
│ │ │ ├───3a
│ │ │ │ 90791ed76a404d3e8c989435a05aa7eb410c51
│ │ │ │ ec19f6a056dda4caa8ba5e19fca54e464e2b9a
│ │ │ │
│ │ │ ├───3d
│ │ │ │ 432b7f63c08364e0535e7cbd26c65c63c648b5
│ │ │ │ 50cf1dcd27ae0d85354ba55b020aa4f816ddb6
│ │ │ │
│ │ │ ├───44
│ │ │ │ 9103a30b9d7bc5870448d0f6ed324d68884579
│ │ │ │
│ │ │ ├───45
│ │ │ │ 41207af798ffa1f235fca585ef77e70daf6a8e
│ │ │ │ 8426bc2e14cb3abed7b96f2f1a931779e1195b
│ │ │ │
│ │ │ ├───4d
│ │ │ │ 515444344c936b46635887590da438c79c81ec
│ │ │ │
│ │ │ ├───54
│ │ │ │ 59cb69a7e536c9437cb4ea4984a2302658a440
│ │ │ │ a8c4aa03c0503537e8b0dc8c65073858abeee9
│ │ │ │
│ │ │ ├───57
│ │ │ │ af4fc2ebda5c5cb77c40b6f4900b2b05bf53a0
│ │ │ │
│ │ │ ├───60
│ │ │ │ 9b3e429c28a58ce7039a2bad2ef4a491155314
│ │ │ │
│ │ │ ├───61
│ │ │ │ b5f59b18d27bc950f2e8fe334c573b8274d22f
│ │ │ │
│ │ │ ├───64
│ │ │ │ 434719a28165c0b7036829cb5d90dcce8ff36a
│ │ │ │
│ │ │ ├───68
│ │ │ │ 52e32d26be4a47de7dc3a87be401ac2815a9cf
│ │ │ │ cc999ab379c511e54f9fb13993730ea0b54296
│ │ │ │
│ │ │ ├───78
│ │ │ │ 8ded0c04ff8dbcb7ccdf2aa089d399fcc4f358
│ │ │ │
│ │ │ ├───84
│ │ │ │ d03810e83fa96d8f4d84fc9cca3e2a19ceb871
│ │ │ │
│ │ │ ├───86
│ │ │ │ 05bb9f069c960e7cb9952d297045fa7e44aa74
│ │ │ │
│ │ │ ├───8f
│ │ │ │ 93558890dd01847ecf569ef5f7ae2761c9e016
│ │ │ │
│ │ │ ├───93
│ │ │ │ f612e1c8fe4adb31f1dc8cb08dc0eb3ae45695
│ │ │ │ f6f78361b97df5c3a174a74d0897d0dcde00b9
│ │ │ │
│ │ │ ├───96
│ │ │ │ ff8ef91d4cf4be4000970bcbaf165e56c119d7
│ │ │ │
│ │ │ ├───97
│ │ │ │ 08f19593cd22c53fd8b3b71aedead25ff64793
│ │ │ │
│ │ │ ├───99
│ │ │ │ 6cc05654376d7b0425936528e317d784724806
│ │ │ │
│ │ │ ├───9a
│ │ │ │ d913202a47eecb0b909db8362d586f584c956b
│ │ │ │
│ │ │ ├───a0
│ │ │ │ 2331f8f11e2794f6f36b25b9fd6f3b36428612
│ │ │ │
│ │ │ ├───a4
│ │ │ │ dc667606fc3197e3bf457697d2453929ef0f1d
│ │ │ │
│ │ │ ├───a6
│ │ │ │ 52c68ca1f01698f38ddd55b73f8663f1354913
│ │ │ │
│ │ │ ├───a9
│ │ │ │ 578757f41ef789f438da94b9426458853a0de0
│ │ │ │
│ │ │ ├───ad
│ │ │ │ 23a6aebabdb8123c87fccfe016003e31c8f967
│ │ │ │ a81e5ba6524043aa18982891c226aac13b92ce
│ │ │ │
│ │ │ ├───af
│ │ │ │ 35d02e690981c67371882740a45af58e4b335b
│ │ │ │
│ │ │ ├───b0
│ │ │ │ 759cd397e761acfa8d3034868ed719c1527b4b
│ │ │ │
│ │ │ ├───b5
│ │ │ │ 8e5a59af4da431bdcd84d26a91f8740dbecc62
│ │ │ │
│ │ │ ├───c1
│ │ │ │ d64e57f97779858b0afdef747a3e50952c2128
│ │ │ │
│ │ │ ├───c8
│ │ │ │ 2b4cd298c2b7fb832c3b9d7a71f242a41b9e45
│ │ │ │ 2d45953e6818fea94c08f9e526242d4e451412
│ │ │ │
│ │ │ ├───cb
│ │ │ │ 9176d8d1cbe3c8bfd9b3d53775398f44274ce1
│ │ │ │
│ │ │ ├───cf
│ │ │ │ 3d36971864f54cddcc77cc54c72864d06268a9
│ │ │ │
│ │ │ ├───d3
│ │ │ │ 3fb4e61bb4c04b78c47010638b56c4e658b3ce
│ │ │ │ 5aa78a875e83ff96f6527a7d6b77ff8a1bfcb6
│ │ │ │
│ │ │ ├───e1
│ │ │ │ 72ea793de97424e15325195c53b344a6d855cd
│ │ │ │ b21ea7a63fb33e0fedb2f73bacb5dcd91bd57f
│ │ │ │
│ │ │ ├───e2
│ │ │ │ 24d8f3b2c11e15fbd7a9869184fa25c105ca8e
│ │ │ │
│ │ │ ├───e4
│ │ │ │ 7f63b4137ab498c42b36b5cb93a6dd8a10accb
│ │ │ │
│ │ │ ├───e6
│ │ │ │ cf29cffb27147e6786dc2971be38bd6e95eb14
│ │ │ │
│ │ │ ├───ee
│ │ │ │ 95d7c4a3adcd9a73800e76209b52ea966615a3
│ │ │ │
│ │ │ ├───ef
│ │ │ │ c3ae2b92cf6fec820ca7a3ad9a64b2e02412a3
│ │ │ │
│ │ │ ├───f7
│ │ │ │ 09b0af23b0a9758b5d5458e2704a9b003dd49c
│ │ │ │
│ │ │ ├───f9
│ │ │ │ a097df37316f512c534e05ee5c07672ff1e7a0
│ │ │ │
│ │ │ ├───fe
│ │ │ │ ebf96df6259edc101651daa647b1f989ea7435
│ │ │ │
│ │ │ ├───info
│ │ │ └───pack
│ │ │ pack-4b251282c949a8ad1225390be8aa4722ec7187c3.idx
│ │ │ pack-4b251282c949a8ad1225390be8aa4722ec7187c3.pack
│ │ │
│ │ └───refs
│ │ ├───heads
│ │ │ master
│ │ │
│ │ ├───remotes
│ │ │ └───origin
│ │ │ HEAD
│ │ │
│ │ └───tags
│ ├───dotfiles
│ │ │ bash_stuff
│ │ │ git-completion.bash
│ │ │
│ │ └───.subversion
│ │ config
│ │
│ └───platform
│ └───osx
│ set-chrome-window-size.oascript
│
└───slickedit
SlickEditOptions20.zip
Any ideas on how to speed up chokidar? Should it’s initial scan do something different? Am I better off doing my own initial scan?
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 2
- Comments: 21 (3 by maintainers)
The watchers are here
https://github.com/microsoft/vscode/tree/master/src/vs/platform/files/node/watcher
On Windows it uses a C# app which it runs in a separate process and looks at its output
https://github.com/microsoft/vscode/tree/master/src/vs/platform/files/node/watcher/win32
Chokidar isn’t just scanning the files, it’s setting file watchers as it goes. Stat polling is very CPU-intensive. Trying to watch a huge directory across a network share is the source of your performance concern. If you just need the scan and not the watching then don’t use chokidar.
It is not likely that you’ll find a significant performance boost for this situation just by optimizing code, but please send a PR if you do. You could do things like run your program on the system where the files are in order to get off of polling.