From efd0158d791247ce35f7089639e8eda8b6937231 Mon Sep 17 00:00:00 2001 From: Roman Konecny Date: Fri, 27 Oct 2023 10:39:20 +0200 Subject: [PATCH] Cache Platform Negotiation in graph build (#9343) * Cache Platform Negotiation in graph build * Clean cached data after build. --- src/Build/Graph/GraphBuilder.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Build/Graph/GraphBuilder.cs b/src/Build/Graph/GraphBuilder.cs index a92da0f73f9..58f9af58bdf 100644 --- a/src/Build/Graph/GraphBuilder.cs +++ b/src/Build/Graph/GraphBuilder.cs @@ -48,6 +48,7 @@ internal class GraphBuilder private readonly ProjectGraph.ProjectInstanceFactoryFunc _projectInstanceFactory; private IReadOnlyDictionary> _solutionDependencies; + private ConcurrentDictionary> _platformNegotiationInstancesCache = new(); public GraphBuilder( IEnumerable entryPoints, @@ -92,6 +93,9 @@ public void BuildGraph() RootNodes = GetGraphRoots(EntryPointNodes); ProjectNodes = allParsedProjects.Values.Select(p => p.GraphNode).ToList(); + + // Clean and release some temporary used large memory objects. + _platformNegotiationInstancesCache.Clear(); } private static IReadOnlyCollection GetGraphRoots(IReadOnlyCollection entryPointNodes) @@ -576,7 +580,7 @@ private List ParseReferences(ProjectGraphNo { var referenceInfos = new List(); - foreach (var referenceInfo in _projectInterpretation.GetReferences(parsedProject.ProjectInstance, _projectCollection, _projectInstanceFactory)) + foreach (var referenceInfo in _projectInterpretation.GetReferences(parsedProject.ProjectInstance, _projectCollection, GetInstanceForPlatformNegotiationWithCaching)) { if (FileUtilities.IsSolutionFilename(referenceInfo.ReferenceConfiguration.ProjectFullPath)) { @@ -594,6 +598,16 @@ private List ParseReferences(ProjectGraphNo return referenceInfos; } + private ProjectInstance GetInstanceForPlatformNegotiationWithCaching( + string projectPath, + Dictionary globalProperties, + ProjectCollection projectCollection) + { + return _platformNegotiationInstancesCache.GetOrAdd( + new ConfigurationMetadata(projectPath, CreatePropertyDictionary(globalProperties)), + new Lazy(() => _projectInstanceFactory(projectPath, globalProperties, projectCollection))).Value; + } + internal static string FormatCircularDependencyError(List projectsInCycle) { var errorMessage = new StringBuilder(projectsInCycle.Select(p => p.Length).Sum());