Glob expansion has been identified as one of the performance bottlenecks when building .NET Core projects. The cost is not negligible with a simple Hello World project and gets progressively worse when the project directory (transitively) contains more files, be it source files or completely unrelated files. Since glob expansion is part of project evaluation, it directly impacts Visual Studio performance as well, especially solution load performance.
This PR is a collection of several changes to the globbing logic aiming to make .NET Core project evaluation faster.
Existing unit tests for correctness, ETL traces for performance.
The wins in terms of the Microsoft-Build/ExpandGlob event duration range from 16% (Hello World project built with
In terms of the overall build time, we're looking at a 1-2% improvement for a Hello World project and 8-10% for a project with thousands of extra files in the source tree.
This PR is recommended to be reviewed commit by commit.
### Context #6151 introduced a regression where `FileMatcher` takes the pattern `*.*` too literally and returns only files that have a dot in the name. `*.*` should be special cased to mean all files in the directory, with or without an extension. ### Changes Made Fixed the regression by explicitly testing for `*.*` and added test coverage. ### Testing Existing and modified unit tests, repro project from dotnet/sdk#16185 (comment). ### Notes Testing for both `*` and `*.*` is already happening elsewhere in the class. MSBuild calls `Directory.EnumerateFileSystemEntries` which under the covers uses `MatchType.Win32` and causes this behavior of unifying `*.*` with `*` on all platforms.
Fixes dotnet#6502 Summary This change fixes a regression in glob matching where files without extension are erroneously not matched when taking a specific globbing code path. Customer impact Any customer who uses a glob pattern susceptible to the bug and has files without extensions in their source tree is affected. The bug was reported by external customers. Regression? Yes, caused by dotnet#6151 where glob matching was optimized which internally made it take a different code path. Changes Made Fixes the regression by properly handling `*.*` to mean all files, not just files with a dot in the name. This convention is used in .NET APIs on all platforms and matches the pre-regression behavior. Testing Added unit test coverage. Also verified locally with the repro provided by the original bug reporter. Risk Low. The star patterns are special-cased to mean all files, other patterns are unaffected.