Skip to content

Commit

Permalink
Reduce ImmutableDictionary allocations in CreateCompilationTrackerMap (
Browse files Browse the repository at this point in the history
…#70319)

* Reduce ImmutableDictionary allocations in CreateCompilationTrackerMap

1) No need to create a builder if _projectIdToTrackerMap is empty
2) No need to create a new ImmutableDictionary if it would end up having the exact same contents as projectIdToTrackerMap
  • Loading branch information
ToddGrun authored Oct 12, 2023
1 parent f0c5469 commit 63cbcad
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1549,12 +1549,27 @@ private static ProjectDependencyGraph CreateDependencyGraph(

private ImmutableDictionary<ProjectId, ICompilationTracker> CreateCompilationTrackerMap(ProjectId changedProjectId, ProjectDependencyGraph dependencyGraph)
{
var builder = ImmutableDictionary.CreateBuilder<ProjectId, ICompilationTracker>();
if (_projectIdToTrackerMap.Count == 0)
return _projectIdToTrackerMap;

using var _ = ArrayBuilder<KeyValuePair<ProjectId, ICompilationTracker>>.GetInstance(_projectIdToTrackerMap.Count, out var newTrackerInfo);
var allReused = true;
foreach (var (id, tracker) in _projectIdToTrackerMap)
builder.Add(id, CanReuse(id) ? tracker : tracker.Fork(tracker.ProjectState, translate: null));
{
var localTracker = tracker;
if (!CanReuse(id))
{
localTracker = tracker.Fork(tracker.ProjectState, translate: null);
allReused = false;
}

return builder.ToImmutable();
newTrackerInfo.Add(new KeyValuePair<ProjectId, ICompilationTracker>(id, localTracker));
}

if (allReused)
return _projectIdToTrackerMap;

return ImmutableDictionary.CreateRange(newTrackerInfo);

// Returns true if 'tracker' can be reused for project 'id'
bool CanReuse(ProjectId id)
Expand Down

0 comments on commit 63cbcad

Please sign in to comment.