From bf5f0cf3805493f64c7a9e516124f9c2f842d1bc Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 28 Feb 2023 12:53:32 -0600 Subject: [PATCH] Avoid delegate allocations in IExtensionManagerExtensions Fixes 2GB allocations seen in https://devdiv.visualstudio.com/0bdbc590-a062-4c3f-b0f6-9383f67865ee/_workitems/edit/1746674. --- .../IExtensionManagerExtensions.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Workspaces/Core/Portable/ExtensionManager/IExtensionManagerExtensions.cs b/src/Workspaces/Core/Portable/ExtensionManager/IExtensionManagerExtensions.cs index 6f80379b1ee24..0f44c6707c040 100644 --- a/src/Workspaces/Core/Portable/ExtensionManager/IExtensionManagerExtensions.cs +++ b/src/Workspaces/Core/Portable/ExtensionManager/IExtensionManagerExtensions.cs @@ -6,6 +6,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Threading.Tasks; @@ -109,12 +110,13 @@ public static async Task PerformFunctionAsync( return defaultValue; } + [SuppressMessage("Style", "IDE0039:Use local function", Justification = "Avoid per-call delegate allocation")] public static Func> CreateNodeExtensionGetter( this IExtensionManager extensionManager, IEnumerable extensions, Func> nodeTypeGetter) { var map = new ConcurrentDictionary>(); - ImmutableArray GetExtensions(Type t1) + Func> getExtensions = (Type t1) => { var query = from e in extensions let types = extensionManager.PerformFunction(e, () => nodeTypeGetter(e), ImmutableArray.Empty) @@ -122,16 +124,17 @@ ImmutableArray GetExtensions(Type t1) select e; return query.ToImmutableArray(); - } + }; - return n => map.GetOrAdd(n.GetType(), GetExtensions); + return n => map.GetOrAdd(n.GetType(), getExtensions); } + [SuppressMessage("Style", "IDE0039:Use local function", Justification = "Avoid per-call delegate allocation")] public static Func> CreateTokenExtensionGetter( this IExtensionManager extensionManager, IEnumerable extensions, Func> tokenKindGetter) { var map = new ConcurrentDictionary>(); - ImmutableArray GetExtensions(int k) + Func> getExtensions = (int k) => { var query = from e in extensions let kinds = extensionManager.PerformFunction(e, () => tokenKindGetter(e), ImmutableArray.Empty) @@ -139,9 +142,9 @@ ImmutableArray GetExtensions(int k) select e; return query.ToImmutableArray(); - } + }; - return t => map.GetOrAdd(t.RawKind, GetExtensions); + return t => map.GetOrAdd(t.RawKind, getExtensions); } } }