Repository: nodejs/node
Pull request: fs: improve globSync performance

<!--
Before submitting a pull request, please read:

- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md
- the commit message formatting guidelines at
  https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

If you believe this PR should be highlighted in the Node.js CHANGELOG
please add the `notable-change` label.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->

Benchmark results:

```
                                                                                    confidence improvement accuracy (*)   (**)  (***)
fs/bench-glob.js recursive='false' mode='async' pattern='*.js' dir='lib' n=1000                    -0.28 %       ±2.63% ±3.50% ±4.56%
fs/bench-glob.js recursive='false' mode='async' pattern='**/*' dir='lib' n=1000                     0.15 %       ±2.85% ±3.81% ±4.98%
fs/bench-glob.js recursive='false' mode='async' pattern='**/**.js' dir='lib' n=1000                -1.03 %       ±2.85% ±3.79% ±4.94%
fs/bench-glob.js recursive='false' mode='sync' pattern='*.js' dir='lib' n=1000                     -0.49 %       ±1.39% ±1.86% ±2.42%
fs/bench-glob.js recursive='false' mode='sync' pattern='**/*' dir='lib' n=1000               *      0.82 %       ±0.68% ±0.91% ±1.19%
fs/bench-glob.js recursive='false' mode='sync' pattern='**/**.js' dir='lib' n=1000         ***      1.38 %       ±0.73% ±0.98% ±1.29%
fs/bench-glob.js recursive='true' mode='async' pattern='*.js' dir='lib' n=1000                      0.31 %       ±2.33% ±3.09% ±4.03%
fs/bench-glob.js recursive='true' mode='async' pattern='**/*' dir='lib' n=1000                     -0.90 %       ±3.45% ±4.59% ±5.98%
fs/bench-glob.js recursive='true' mode='async' pattern='**/**.js' dir='lib' n=1000                  0.26 %       ±2.46% ±3.28% ±4.26%
fs/bench-glob.js recursive='true' mode='sync' pattern='*.js' dir='lib' n=1000                       0.01 %       ±0.92% ±1.23% ±1.60%
fs/bench-glob.js recursive='true' mode='sync' pattern='**/*' dir='lib' n=1000                       0.57 %       ±0.62% ±0.83% ±1.09%
fs/bench-glob.js recursive='true' mode='sync' pattern='**/**.js' dir='lib' n=1000           **      1.89 %       ±1.35% ±1.82% ±2.41%

Be aware that when doing many comparisons the risk of a false-positive result increases.
In this case, there are 12 comparisons, you can thus expect the following amount of false-positive results:
  0.60 false positives, when considering a   5% risk acceptance (*, **, ***),
  0.12 false positives, when considering a   1% risk acceptance (**, ***),
  0.01 false positives, when considering a 0.1% risk acceptance (***)
```


Changed files:
filename: lib/internal/fs/glob.js
patch: @@ -331,10 +331,7 @@ class Glob {
     const fullpath = resolve(this.#root, path);
 
     // If path is a directory, add trailing slash and test patterns again.
-    // TODO(Trott): Would running #isExcluded() first and checking isDirectory() only
-    // if it matches be more performant in the typical use case? #isExcluded()
-    // is often ()=>false which is about as optimizable as a function gets.
-    if (this.#cache.statSync(fullpath).isDirectory() && this.#isExcluded(`${fullpath}/`)) {
+    if (this.#isExcluded(`${fullpath}/`) && this.#cache.statSync(fullpath).isDirectory()) {
       return;
     }