msbuild: ResolveAssemblyReference is slow on .NET Core with many references
ResolveAssemblyReferences
runs unconditionally even on incremental builds (because the user may have installed a targeting pack or, for full-framework scenarios, GACed an assembly). This makes it performance-sensitive.
With the advent of .NET Core micro-assemblies, it has become common to pass many, many references to RAR. This exacerbates performance problems.
@rynowak was kind enough to run a profiler to see this:
About this issue
- Original URL
- State: open
- Created 7 years ago
- Reactions: 18
- Comments: 64 (62 by maintainers)
Commits related to this issue
- Use AssemblyName.Clone when possible. AssemblyName.Clone is not available in early versions of .NET Core. Until we can upgrade MSBuild to use .NET Core 2.0, we can't call the Clone method directly. Th... — committed to AndyGerlicher/msbuild by AndyGerlicher 7 years ago
- Use AssemblyName.Clone when possible. AssemblyName.Clone is not available in early versions of .NET Core. Until we can upgrade MSBuild to use .NET Core 2.0, we can't call the Clone method directly. Th... — committed to AndyGerlicher/msbuild by AndyGerlicher 7 years ago
- Use AssemblyName.Clone when possible. AssemblyName.Clone is not available in early versions of .NET Core. Until we can upgrade MSBuild to use .NET Core 2.0, we can't call the Clone method directly. Th... — committed to AndyGerlicher/msbuild by AndyGerlicher 7 years ago
- Use AssemblyName.Clone when possible. AssemblyName.Clone is not available in early versions of .NET Core. Until we can upgrade MSBuild to use .NET Core 2.0, we can't call the Clone method directly. Th... — committed to AndyGerlicher/msbuild by AndyGerlicher 7 years ago
- Use AssemblyName.Clone when possible. AssemblyName.Clone is not available in early versions of .NET Core. Until we can upgrade MSBuild to use .NET Core 2.0, we can't call the Clone method directly. Th... — committed to AndyGerlicher/msbuild by AndyGerlicher 7 years ago
- Use AssemblyName.Clone when possible. (#2016) AssemblyName.Clone() is not available in early versions of .NET Core. Until we can upgrade MSBuild to use .NET Core 2.0, we can't call the Clone method... — committed to dotnet/msbuild by AndyGerlicher 7 years ago
- Use AssemblyName.Clone when possible. (#2016) AssemblyName.Clone() is not available in early versions of .NET Core. Until we can upgrade MSBuild to use .NET Core 2.0, we can't call the Clone method... — committed to dotnet/msbuild by AndyGerlicher 7 years ago
- Merge pull request #2192 from rainersigwald/rar/combine-assemblyinfo-reads RAR performance improvements (related to #2015). — committed to dotnet/msbuild by rainersigwald 7 years ago
Now that a few of these changes are in, I’ve taken some quick sample performance summaries building a couple .NET Core projects using the current tip of mater https://github.com/Microsoft/msbuild/commit/b630e674c729787d57a485ef5338915643eb1cea to show improvements we’ve made in RAR times since 15.9, although there’s still plenty of room for improvement. These are all 3rd builds, incremental no-op. Included single-proc since multi-proc timings are added cumulatively across processes, but still useful to see.
MSBuild 15.9
WebLargeCore Single-Proc
WebLargeCore Multi-Proc
OrchardCore Single-Proc
OrchardCore Multi-Proc
MSBuild Master
WebLargeCore Single-Proc (-44% RAR time)
WebLargeCore Multi-Proc
OrchardCore Single-Proc (-47% RAR time)
OrchardCore Multi-Proc
I just collected some data from a dotnet/runtime libraries build with ~1400 evaluations (outer + inner builds). I crossed out the tasks that are dotnet/runtime specific (a fix for ValidatePackage no-op build times is tracked via https://github.com/dotnet/sdk/issues/23517).
Assuming RAR only runs in inner-builds, this should represent the time it takes RAR to serve ~1100 inner builds. I was looking into speeding up incremental builds in dotnet/runtime libs and I believe the highest impact contributors on the msbuild side are:
23% are dotnet/runtime specific and must be fixed by ourselves. Just wanted to share this data in case it helps.
Han, maybe exactly what I’m looking for, gonna try that, thanks 👍
One thing of note: MSBuild only calls that
AssemblyName
constructor becauseAssemblyName.Clone()
isn’t available in .NET Standard 1.x. One possible improvement here would be to move to .NET Core 2.0.