-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Closed
Labels
Description
Many methods in Microsoft.CodeAnalysis.ProjectChanges work by building a temporary hashset to compare a list of items between OldProject and NewProject. This came up as a hot spot during a profiling session, for a function that does something like:
var solutionChanges = currentSolution.GetChanges(oldSolution);
foreach (var projectChanges in solutionChanges.GetProjectChanges())
{
var addedAnalyzerReferences = projectChanges.GetAddedAnalyzerReferences();
...
}If there are no actual changes (which I expect to be the most common case), GetAddedAnalyzerReferences will still create a hashset and go over the whole collection. I believe this can be optimized with a simple check:
public IEnumerable<AnalyzerReference> GetAddedAnalyzerReferences()
{
// Fast-path
if (NewProject.AnalyzerReferences.Equals(OldProject.AnalyzerReferences))
{
yield break;
}
// Old logic
var oldAnalyzerReferences = new HashSet<AnalyzerReference>(OldProject.AnalyzerReferences);
foreach (var analyzerReference in NewProject.AnalyzerReferences)
{
if (!oldAnalyzerReferences.Contains(analyzerReference))
{
yield return analyzerReference;
}
}
}Same thing for all the methods in ProjectChanges that use a similar pattern. It adds a negligible cost when the collections are different, and greatly reduces the cost when the collections are identical.
Reactions are currently unavailable