Skip to content

Commit

Permalink
Merge pull request #22185 from heejaechang/portChecksum
Browse files Browse the repository at this point in the history
back ported only portion that is causing perf issues in dev15.4.x fro…
  • Loading branch information
heejaechang authored Sep 21, 2017
2 parents 0f4bca1 + 0ad3ed0 commit ab56a4a
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,12 @@ public static Checksum GetMetadataChecksum(
{
// We can reuse the index for any given reference as long as it hasn't changed.
// So our checksum is just the checksum for the PEReference itself.
var serializer = new Serializer(solution.Workspace);
var checksum = serializer.CreateChecksum(reference, cancellationToken);
return checksum;
return ChecksumCache.GetOrCreate(reference, _ =>
{
var serializer = new Serializer(solution.Workspace);
var checksum = serializer.CreateChecksum(reference, cancellationToken);
return checksum;
});
}

private static Task<SymbolTreeInfo> TryLoadOrCreateMetadataSymbolTreeInfoAsync(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Collections;
Expand Down Expand Up @@ -41,22 +40,37 @@ public static Task<SymbolTreeInfo> GetInfoForSourceAssemblyAsync(
return result;
}

public static async Task<Checksum> GetSourceSymbolsChecksumAsync(Project project, CancellationToken cancellationToken)
/// <summary>
/// Cache of project to the checksum for it so that we don't have to expensively recompute
/// this each time we get a project.
/// </summary>
private static ConditionalWeakTable<ProjectState, AsyncLazy<Checksum>> s_projectToSourceChecksum =
new ConditionalWeakTable<ProjectState, AsyncLazy<Checksum>>();

public static Task<Checksum> GetSourceSymbolsChecksumAsync(Project project, CancellationToken cancellationToken)
{
var lazy = s_projectToSourceChecksum.GetValue(
project.State, p => new AsyncLazy<Checksum>(c => ComputeSourceSymbolsChecksumAsync(p, c), cacheResult: true));

return lazy.GetValueAsync(cancellationToken);
}

private static async Task<Checksum> ComputeSourceSymbolsChecksumAsync(ProjectState projectState, CancellationToken cancellationToken)
{
// The SymbolTree for source is built from the source-symbols from the project's compilation's
// assembly. Specifically, we only get the name, kind and parent/child relationship of all the
// child symbols. So we want to be able to reuse the index as long as none of these have
// changed. The only thing that can make those source-symbols change in that manner are if
// the text of any document changes, or if options for the project change. So we build our
// checksum out of that data.
var serializer = new Serializer(project.Solution.Workspace);
var projectStateChecksums = await project.State.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false);
var serializer = new Serializer(projectState.LanguageServices.WorkspaceServices);
var projectStateChecksums = await projectState.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false);

// Order the documents by FilePath. Default ordering in the RemoteWorkspace is
// to be ordered by Guid (which is not consistent across VS sessions).
var textChecksumsTasks = project.Documents.OrderBy(d => d.FilePath).Select(async d =>
var textChecksumsTasks = projectState.DocumentStates.OrderBy(d => d.Value.FilePath).Select(async d =>
{
var documentStateChecksum = await d.State.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false);
var documentStateChecksum = await d.Value.GetStateChecksumsAsync(cancellationToken).ConfigureAwait(false);
return documentStateChecksum.Text;
});

Expand Down Expand Up @@ -96,7 +110,7 @@ internal static async Task<SymbolTreeInfo> CreateSourceSymbolTreeInfoAsync(
GenerateSourceNodes(assembly.GlobalNamespace, unsortedNodes, s_getMembersNoPrivate);

return CreateSymbolTreeInfo(
project.Solution, checksum, project.FilePath, unsortedNodes.ToImmutableAndFree(),
project.Solution, checksum, project.FilePath, unsortedNodes.ToImmutableAndFree(),
inheritanceMap: new OrderPreservingMultiDictionary<string, string>());
}

Expand Down

0 comments on commit ab56a4a

Please sign in to comment.