Skip to content

Commit

Permalink
Use a pooled StringBuilder in Dependency.GetID
Browse files Browse the repository at this point in the history
Traces showed this taking upward of 1% of allocations of opening a solution.

Fixes dotnet#2918.
  • Loading branch information
Pilchie committed Jan 17, 2018
1 parent 885db10 commit 6e832b9
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
// 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.Concurrent;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Imaging.Interop;
using Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.CrossTarget;
using Microsoft.VisualStudio.ProjectSystem.VS.Utilities;
using Microsoft.VisualStudio.Text;

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.Snapshot
{
internal class Dependency : IDependency
{
private static ConcurrentBag<StringBuilder> s_builderPool = new ConcurrentBag<StringBuilder>();

// These priorities are for graph nodes only and are used to group graph nodes
// appropriatelly in order groups predefined order instead of alphabetically.
// Order is not changed for top dependency nodes only for grpah hierarchies.
Expand Down Expand Up @@ -331,7 +336,25 @@ public static string GetID(ITargetFramework targetFramework, string providerType
Requires.NotNullOrEmpty(providerType, nameof(providerType));
Requires.NotNullOrEmpty(modelId, nameof(modelId));

return $"{targetFramework.ShortName}\\{providerType}\\{Normalize(modelId)}".TrimEnd(CommonConstants.BackSlashDelimiter);
StringBuilder sb = null;
try
{
int length = targetFramework.ShortName.Length + providerType.Length + 2;
if (!s_builderPool.TryTake(out sb))
{
sb = new StringBuilder(length);
}

sb.Append(targetFramework.ShortName).Append('\\');
sb.Append(providerType).Append('\\');
sb.Append(Normalize(modelId));
sb.TrimEnd(CommonConstants.BackSlashDelimiter);
return sb.ToString();
}
finally
{
s_builderPool.Add(sb);
}
}

private static string GetFullPath(string originalItemSpec, string containingProjectPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,29 @@ public static void AppendFormat(this StringBuilder builder, StringFormat format)
builder.AppendFormat(format.Format, format.Arguments);
}
}

public static StringBuilder TrimEnd(this StringBuilder builder, params char[] trimChars)
{
while (builder.Length > 0)
{
var match = false;
foreach (var c in trimChars)
{
if (builder[builder.Length - 1] == c)
{
match = true;
builder.Length--;
break;
}
}

if (!match)
{
return builder;
}
}

return builder;
}
}
}

0 comments on commit 6e832b9

Please sign in to comment.