Description
Is your feature request related to a problem? Please describe.
@DamianEdwards pointed me at this review of the macbook w/ M4 Max processor over the weekend (timestamp is directly to the comparison I'll be talking about).
The repo in question is https://github.com/alexziskind1/machine_tests.
The gist is that a very large (over 100k) number of C# source files are generated, and then dotnet restore
followed by dotnet build
are called, and this is treated as a performance test.
I took binlogs on my Windows and WSL Ubuntu instances, and Damian took binlogs on his Ubuntu machine and his Mac, all with eval profiling enabled. This is accomplished by adding -bl
to enable binlog generation, and --profileevaluation
to get nice graphs of where eval time is spent. As seasoned MSBuild experts might expect, the problem is file globbing here - the vast majority of the time in the build is spent in (on my Windows machine):
- SDK Default Compile Item Include globbing
- Csc - this is out of our control, compiling 100k files just takes time
However, in the test thread @alexziskind1 is doing, he's evaluating 5 times total (times on my Windows box):
dotnet restore
- once before the
Restore
target is executed, withMSBuildRestoreSessionId
andMSBuildIsRestoring
properties set (45s) - once as a side effect of the
_FilterRestoreGraphProjectInputItems
task when it calls theMSBuild
Task on the same projects'_IsProjectRestoreSupported
Target, but with an additional Global PropertyExcludeRestorePackageImports
set (45s)
- once before the
- dotnet build (with implicit restore because
--no-restore
is not passed in)- the same two from above, and
- the 'normal' evaluation of the project without any of the Restore-related properties set (45s)
On my machine, this means that we spend ~2.25 minutes just on evaluations, almost all of which is globbing, and ~2m on actual compilation (Csc Task wall-clock time).
Describe the solution you'd like
Restore
doesn't generally need to do Default Item expansion (this is pretty common on other commands that do MSBuild evaluation like dotnet run
, so the dotnet cli
should add the --restoreproperty:EnableDefaultItems=false
argument to the command line that it constructs for any implicit restore it asks MSBuild to perform.
If we wanted to be very defensive here, we could also
- enlighten the
dotnet
CLI about the MSBuild--restoreproperty
CLI argument like we have for the MSBuild--property
CLI argument - parse any user-supplied input for this argument, and if the user has specified a
EnableDefaultItems
value do not add our own
Additional context
If we do this, then on my machine at least every Restore-related evaluation goes from ~45s to ~300ms. That's a huge savings, amortized.