From 219cb1298124bb5efba11f1b1d10bf9286ffbe70 Mon Sep 17 00:00:00 2001 From: Todd Grunke Date: Mon, 31 Mar 2025 12:55:56 -0700 Subject: [PATCH 1/3] Avoid computations in AnalyzerAssemblyLoader.AddDependencyLocation Currently, this method is calculating some data upfront for the value part of a TryAdd call. Instead, defer calculating that data until after we've determine it's not already in the dictionary. I saw this accounting for 2.3% of CPU during loading Roslyn.sln. With this change, it was about 0.2%. --- .../DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs index 36e2fad512fc3..ee60f80657056 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs @@ -144,6 +144,15 @@ public void AddDependencyLocation(string originalPath) { CheckIfDisposed(); + lock (_guard) + { + if (_originalPathInfoMap.TryGetValue(originalPath, out var originalPathInfo)) + { + Debug.Assert(GeneratedPathComparer.Equals(_originalPathInfoMap[originalPath].ResolvedPath, originalPathInfo.ResolvedPath)); + return; + } + } + CompilerPathUtilities.RequireAbsolutePath(originalPath, nameof(originalPath)); var simpleName = PathUtilities.GetFileName(originalPath, includeExtension: false); string resolvedPath = originalPath; From 89c67ff57172503fc12d45f24595ae92f2d5df24 Mon Sep 17 00:00:00 2001 From: Todd Grunke Date: Mon, 31 Mar 2025 14:16:35 -0700 Subject: [PATCH 2/3] Remove assert that wasn't providing value --- .../Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs index ee60f80657056..adb6296a63907 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs @@ -146,9 +146,8 @@ public void AddDependencyLocation(string originalPath) lock (_guard) { - if (_originalPathInfoMap.TryGetValue(originalPath, out var originalPathInfo)) + if (_originalPathInfoMap.ContainsKey(originalPath)) { - Debug.Assert(GeneratedPathComparer.Equals(_originalPathInfoMap[originalPath].ResolvedPath, originalPathInfo.ResolvedPath)); return; } } From 74243e70111ab4a2d82fb7caa63ade28d8a06f7c Mon Sep 17 00:00:00 2001 From: Todd Grunke Date: Mon, 31 Mar 2025 17:38:00 -0700 Subject: [PATCH 3/3] Change code to match test expectations around exceptions --- .../Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs index adb6296a63907..da4e4cc62478b 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs @@ -144,6 +144,8 @@ public void AddDependencyLocation(string originalPath) { CheckIfDisposed(); + CompilerPathUtilities.RequireAbsolutePath(originalPath, nameof(originalPath)); + lock (_guard) { if (_originalPathInfoMap.ContainsKey(originalPath)) @@ -152,7 +154,6 @@ public void AddDependencyLocation(string originalPath) } } - CompilerPathUtilities.RequireAbsolutePath(originalPath, nameof(originalPath)); var simpleName = PathUtilities.GetFileName(originalPath, includeExtension: false); string resolvedPath = originalPath; IAnalyzerPathResolver? resolver = null;