Skip to content

Commit 447efab

Browse files
committed
Improve perf of accessing configured value
Fixes #2707 Lifeng reported that calling `GetActiveConfiguredProjectExports` on the base class was taking 0.5 seconds of CPU while loading Roslyn.sln. This change uses `IActiveConfiguredValue<>` to cache the instance, to improve performance while building dependencies trees across the solution during solution load.
1 parent 0a0e2ce commit 447efab

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/Tree/Dependencies/DependenciesTreeProvider.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ internal sealed partial class DependenciesTreeProvider : ProjectTreeProviderBase
4747
private readonly OrderPrecedenceImportCollection<IProjectTreeActionHandler> _removalActionHandlers;
4848

4949
private readonly DependenciesSnapshotProvider _dependenciesSnapshotProvider;
50+
private readonly IActiveConfiguredValue<IConfiguredProjectExports> _activeConfiguredProjectExports;
5051
private readonly CancellationSeries _treeUpdateCancellationSeries;
5152
private readonly IProjectAccessor _projectAccessor;
5253
private readonly ITaskDelayScheduler _debounce;
@@ -68,11 +69,13 @@ public DependenciesTreeProvider(
6869
IProjectThreadingService threadingService,
6970
IUnconfiguredProjectTasksService tasksService,
7071
IProjectAccessor projectAccessor,
71-
DependenciesSnapshotProvider dependenciesSnapshotProvider)
72+
DependenciesSnapshotProvider dependenciesSnapshotProvider,
73+
IActiveConfiguredValue<IConfiguredProjectExports> activeConfiguredProjectExports)
7274
: base(threadingService, unconfiguredProject)
7375
{
7476
_dependenciesSnapshotProvider = dependenciesSnapshotProvider;
7577
_projectAccessor = projectAccessor;
78+
_activeConfiguredProjectExports = activeConfiguredProjectExports;
7679

7780
_removalActionHandlers = new OrderPrecedenceImportCollection<IProjectTreeActionHandler>(
7881
ImportOrderPrecedenceComparer.PreferenceOrder.PreferredComesFirst,
@@ -377,7 +380,7 @@ await _projectAccessor.OpenProjectForWriteAsync(ActiveConfiguredProject, project
377380

378381
protected override ConfiguredProjectExports GetActiveConfiguredProjectExports(ConfiguredProject newActiveConfiguredProject)
379382
{
380-
return GetActiveConfiguredProjectExports<MyConfiguredProjectExports>(newActiveConfiguredProject);
383+
return (ConfiguredProjectExports)_activeConfiguredProjectExports.Value;
381384
}
382385

383386
#region ITreeConstruction
@@ -479,14 +482,12 @@ IProjectItemTree2 IProjectTreeOperations.NewTree(string caption, IProjectPropert
479482
/// <summary>
480483
/// Describes services collected from the active configured project.
481484
/// </summary>
482-
[Export]
483-
private sealed class MyConfiguredProjectExports : ConfiguredProjectExports
485+
[Export(typeof(IConfiguredProjectExports))]
486+
[method: ImportingConstructor]
487+
private sealed class MyConfiguredProjectExports(ConfiguredProject configuredProject)
488+
: ConfiguredProjectExports(configuredProject),
489+
IConfiguredProjectExports
484490
{
485-
[ImportingConstructor]
486-
public MyConfiguredProjectExports(ConfiguredProject configuredProject)
487-
: base(configuredProject)
488-
{
489-
}
490491
}
491492

492493
/// <summary>
@@ -504,4 +505,7 @@ public ProjectDependencyTreeRemovalActionHandlerContext(IProjectTreeProvider tre
504505
TreeProvider = treeProvider;
505506
}
506507
}
508+
509+
// NOTE this interface is needed to work around accessiblity issues when making MyConfiguredProjectExports non-private
510+
internal interface IConfiguredProjectExports { }
507511
}

0 commit comments

Comments
 (0)