From 6547e217ef3cc821f9f78acd22295242a37f6dc9 Mon Sep 17 00:00:00 2001 From: Todd Grunke Date: Tue, 15 Aug 2023 07:42:50 -0700 Subject: [PATCH] Reduce LOH allocations for SemanticToken classification in LSP (#69496) * Reduce LOH allocations for SemanticToken classification in LSP LSP semantic classification classifies the whole document per call. This ends up with a large number of classifiedspans per call, enough so that the standard ArrayBuilder cache ends up throwing away it's values upon Free. Instead, use the Classifier's pooled list, as it doesn't have the size limit for it's cache. This accounts for about 0.5% of LOH allocations in the devenv process in the customer profile that I'm looking at. * Remove accidental remnants of earlier attempt I made locally and didn't fullly revert. --- .../Handler/SemanticTokens/SemanticTokensHelpers.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Handler/SemanticTokens/SemanticTokensHelpers.cs b/src/Features/LanguageServer/Protocol/Handler/SemanticTokens/SemanticTokensHelpers.cs index 21a2fc5b28bda..eccc0df2cb0ef 100644 --- a/src/Features/LanguageServer/Protocol/Handler/SemanticTokens/SemanticTokensHelpers.cs +++ b/src/Features/LanguageServer/Protocol/Handler/SemanticTokens/SemanticTokensHelpers.cs @@ -4,11 +4,11 @@ using System; using System.Collections.Generic; -using System.Collections.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Classification; +using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -59,7 +59,7 @@ private static async Task GetClassifiedSpansForDocumentAsync( CancellationToken cancellationToken) { var classificationService = document.GetRequiredLanguageService(); - using var _ = ArrayBuilder.GetInstance(out var classifiedSpans); + using var _ = Classifier.GetPooledList(out var classifiedSpans); // We always return both syntactic and semantic classifications. If there is a syntactic classifier running on the client // then the semantic token classifications will override them. @@ -82,7 +82,7 @@ private static async Task GetClassifiedSpansForDocumentAsync( public static ClassifiedSpan[] ConvertMultiLineToSingleLineSpans(SourceText text, ClassifiedSpan[] classifiedSpans) { - using var _ = ArrayBuilder.GetInstance(out var updatedClassifiedSpans); + using var _ = Classifier.GetPooledList(out var updatedClassifiedSpans); for (var spanIndex = 0; spanIndex < classifiedSpans.Length; spanIndex++) { @@ -109,7 +109,7 @@ public static ClassifiedSpan[] ConvertMultiLineToSingleLineSpans(SourceText text static void ConvertToSingleLineSpan( SourceText text, ClassifiedSpan[] originalClassifiedSpans, - ArrayBuilder updatedClassifiedSpans, + SegmentedList updatedClassifiedSpans, ref int spanIndex, string classificationType, int startLine,