Skip to content

SDK should disable default item globbing when asking MSBuild to perform implicit Restores #49415

Open
@baronfel

Description

@baronfel

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, with MSBuildRestoreSessionId and MSBuildIsRestoring properties set (45s)
    • once as a side effect of the _FilterRestoreGraphProjectInputItems task when it calls the MSBuild Task on the same projects' _IsProjectRestoreSupported Target, but with an additional Global Property ExcludeRestorePackageImports set (45s)
  • 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.

Metadata

Metadata

Assignees

Labels

Area-CLIcli-uxIssues and PRs that deal with the UX of the CLI (exit codes, log output, verbs/options, and so on)performanceuntriagedRequest triage from a team member

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions