-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize SDK resolution in dotnet build #9657
Conversation
@dsplaisted, do you think we can avoid resolving |
There's not an easy way to do this, because that SDK is imported before we know whether workloads are going to be used. Even if we got rid of that import, we would still then import I think to speed this up we would need to speed up the resolver itself, or find a way to cache its data better. |
Thank you. Can we realistically defer these imports until |
@ladipro A project doesn't explicitly specify an MSBuild SDK import to depend on a workload. Workloads can be enabled by any MSBuild property, and that mapping is defined in the WorkloadManifest.targets file of each workload manifest. For example, if the target platform is Android, then the Android workload will be required, and the Basically we can't know whether a project uses a workload or not without first running the workloads resolver and processing the .targets files that come from the workload manifests. |
Ah, I was completely off base then. Ok, so the next best thing we can do is have resolvers statically declare their priority so at least the NuGet resolver is pay-for-play - loaded and called only when actually needed. That should be mostly MSBuild work. Anyway, thank you! |
Fixes #9506
Context
In
dotnet build
, resolving in-box Sdk's has suboptimal performance. Resolver assemblies are loaded into the process even in cases where the project asks for Sdk's likeMicrosoft.NET.Sdk
, which can be looked up trivially. And in fact, they are looked up trivially but only after resolver assemblies have been loaded and invoked.The inefficiency is shown by the recently added logging:
There is also a subtle and confusing functional difference between
MSBuild.exe
anddotnet build
where a NuGet package may take precedence over an in-box Sdk indotnet build
, but the same is not possible inMSBuild.exe
.Changes Made
Made the default resolver handle the Sdk resolution first, before external resolvers are consulted. This is better perf-wise and aligns with
MSBuild.exe
, please see the large code comment for details.This eliminates all but the last log event:
The SDK "Microsoft.NET.Sdk" was successfully resolved by the "DefaultSdkResolver" resolver to location "C:\Program Files\dotnet\sdk\9.0.100-alpha.1.24067.2\Sdks\Microsoft.NET.Sdk\Sdk" and version "".
Testing
Existing and new unit tests, manual testing of various builds.
Perf testing:
dotnet build
that builds a project depending on in-box Sdks is ~10 ms faster and loads 5 fewer assemblies, as long as it's built withMSBuildEnableWorkloadResolver=false
(see below).Notes
While we don't have to ask the
MSBuildWorkloadSdkResolver
andNuGetSdkResolver
to resolve in-box Sdk's anymore, this change is unfortunately not avoiding these resolvers in most builds. They are still loaded to resolve the specialMicrosoft.NET.SDK.WorkloadAutoImportPropsLocator
Sdk, unless workloads are disabled.