Repository: node
Issue: FSWatcher.close() incurs a big performance cost in >=10.16
Labels: fs

<!--
Thank you for reporting a possible bug in Node.js.

Please fill in as much of the template below as you can.

Version: output of `node -v`
Platform: output of `uname -a` (UNIX), or version and 32 or 64-bit (Windows)
Subsystem: if known, please specify the affected core module name

If possible, please provide code that demonstrates the problem, keeping it as
simple and free of external dependencies as you can.
-->

* **Version**: 10.16
* **Platform**: Mac
* **Subsystem**: fs

<!-- Please provide more details below this comment. -->

There seems to have been a massive performance decrease in FSWatcher.close() introduced in 10.16.

I use `ts-node-dev` as a file watcher when developing web applications, which under the hood uses `filewatcher`. 

I believe the following commits/PRs could be contributing? Not smart enough to tell you why though 😅 
- #19345
- #19089

Some examples w/ a pretty small express app:

#### 10.15
```
$ nvm use 10.15
$ tsnd src/index 
```
save some files...
```
Using ts-node version 8.4.1, typescript version 3.6.4
[INFO] 17:03:16 Restarting: manual restart from user
removing 962 watchers
watcher.removeAll: 5.162ms
Using ts-node version 8.4.1, typescript version 3.6.4
[INFO] 17:03:17 Restarting: manual restart from user
removing 962 watchers
watcher.removeAll: 3.997ms
Using ts-node version 8.4.1, typescript version 3.6.4
[INFO] 17:03:18 Restarting: manual restart from user
removing 962 watchers
watcher.removeAll: 3.915ms
Using ts-node version 8.4.1, typescript version 3.6.4
[INFO] 17:03:18 Restarting: manual restart from user
removing 921 watchers
watcher.removeAll: 2.992ms
```

#### 10.16

```
$ nvm use 10.16
$ tsnd src/index
```
save some files...
```
Using ts-node version 8.4.1, typescript version 3.6.4
[INFO] 17:05:20 Restarting: manual restart from user
removing 962 watchers
watcher.removeAll: 8631.891ms
Using ts-node version 8.4.1, typescript version 3.6.4
[INFO] 17:05:31 Restarting: manual restart from user
removing 962 watchers
watcher.removeAll: 8679.892ms
Using ts-node version 8.4.1, typescript version 3.6.4
[INFO] 17:05:42 Restarting: manual restart from user
removing 962 watchers
watcher.removeAll: 8679.248ms
Using ts-node version 8.4.1, typescript version 3.6.4
[INFO] 17:05:51 Restarting: manual restart from user
removing 962 watchers
watcher.removeAll: 8764.230ms
Using ts-node version 8.4.1, typescript version 3.6.4
```

#### Method

Perf code added to the following: https://github.com/fgnass/filewatcher/blob/master/index.js#L130

```
FileWatcher.prototype.removeAll = function() {
  console.time("watcher.removeAll");
  console.log(`removing ${this.list().length} watchers`);
  this.list().forEach(this.remove, this);
  console.timeEnd("watcher.removeAll");
};
```

One might be tempted to think the `list()` method could be slow, however adding code right above it, a single invocation of watcher.close() took longer than all of them in 10.15.
```
watcher.close ~/project/node_modules/date-fns/getISOWeekYear/index.js: 6.616ms
watcher.close ~/project/node_modules/date-fns/startOfISOWeek/index.js: 6.514ms
watcher.close ~/project/node_modules/date-fns/startOfWeek/index.js: 6.731ms
watcher.close ~/project/node_modules/date-fns/setISOWeekYear/index.js: 6.540ms
watcher.close ~/project/node_modules/date-fns/startOfISOWeekYear/index.js: 6.447ms
watcher.close ~/project/node_modules/date-fns/differenceInCalendarDays/index.js: 6.563ms
watcher.close ~/project/node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds/index.js: 6.465ms
```