Skip to content

Commit ee4e077

Browse files
authored
Add StringIntern for Item and Property Functions. (#9024)
Remove duplicated strings from Item and Property Function. Intern these strings to reduce memory usage. Context Strings used parsing Item and Property Function are duplicated many times, common offenders are "Contains", "Strings", and "true". Changes Made Use the Strings.WeakIntern() tool to cache the strings. Since these are common strings which are shared among projects, use the global String store instead of the project specific store. Testing Profiled with the Visual Studio Memory Inspector. This reduced 5-6mb of strings saved in our internal Repro of 200 projects. Notes There are still other places here duplicate string exists, this PR focus only on these locations.
1 parent 9394ada commit ee4e077

File tree

2 files changed

+6
-9
lines changed

2 files changed

+6
-9
lines changed

src/Build/Evaluation/Expander.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3315,7 +3315,7 @@ internal static Function<T> ExtractPropertyFunction(
33153315
ProjectErrorUtilities.ThrowInvalidProject(elementLocation, "InvalidFunctionStaticMethodSyntax", expressionFunction, String.Empty);
33163316
}
33173317

3318-
var typeName = expressionRoot.Slice(1, typeEndIndex - 1).ToString();
3318+
var typeName = Strings.WeakIntern(expressionRoot.Slice(1, typeEndIndex - 1));
33193319
var methodStartIndex = typeEndIndex + 1;
33203320

33213321
if (expressionRoot.Length > methodStartIndex + 2 && expressionRoot[methodStartIndex] == ':' && expressionRoot[methodStartIndex + 1] == ':')
@@ -3373,7 +3373,7 @@ internal static Function<T> ExtractPropertyFunction(
33733373
var rootEndIndex = expressionRoot.IndexOf('.');
33743374

33753375
// If this is an instance function rather than a static, then we'll capture the name of the property referenced
3376-
var functionReceiver = expressionRoot.Slice(0, rootEndIndex).Trim().ToString();
3376+
var functionReceiver = Strings.WeakIntern(expressionRoot.Slice(0, rootEndIndex).Trim());
33773377

33783378
// If propertyValue is null (we're not recursing), then we're expecting a valid property name
33793379
if (propertyValue == null && !IsValidPropertyName(functionReceiver))

src/Build/Evaluation/ExpressionShredder.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,7 @@ internal static List<ItemExpressionCapture> GetReferencedItemExpressions(string
156156

157157
// Grab the name, but continue to verify it's a well-formed expression
158158
// before we store it.
159-
string name = expression.Substring(startOfName, i - startOfName);
160-
161-
// return the item that we're working with
162-
string itemName = name;
159+
string itemName = Microsoft.NET.StringTools.Strings.WeakIntern(expression.AsSpan(startOfName, i - startOfName));
163160

164161
SinkWhitespace(expression, ref i);
165162
bool transformOrFunctionFound = true;
@@ -251,10 +248,10 @@ internal static List<ItemExpressionCapture> GetReferencedItemExpressions(string
251248
subExpressions = new List<ItemExpressionCapture>();
252249
}
253250

254-
// Create an expression capture that encompases the entire expression between the @( and the )
251+
// Create an expression capture that encompasses the entire expression between the @( and the )
255252
// with the item name and any separator contained within it
256253
// and each transform expression contained within it (i.e. each ->XYZ)
257-
ItemExpressionCapture expressionCapture = new ItemExpressionCapture(startPoint, endPoint - startPoint, expression.Substring(startPoint, endPoint - startPoint), itemName, separator, separatorStart, transformExpressions);
254+
ItemExpressionCapture expressionCapture = new ItemExpressionCapture(startPoint, endPoint - startPoint, Microsoft.NET.StringTools.Strings.WeakIntern(expression.AsSpan(startPoint, endPoint - startPoint)), itemName, separator, separatorStart, transformExpressions);
258255
subExpressions.Add(expressionCapture);
259256

260257
continue;
@@ -601,7 +598,7 @@ private static ItemExpressionCapture SinkItemFunctionExpression(string expressio
601598

602599
if (endFunctionArguments > startFunctionArguments)
603600
{
604-
capture.FunctionArguments = expression.Substring(startFunctionArguments, endFunctionArguments - startFunctionArguments);
601+
capture.FunctionArguments = Microsoft.NET.StringTools.Strings.WeakIntern(expression.AsSpan(startFunctionArguments, endFunctionArguments - startFunctionArguments));
605602
}
606603

607604
return capture;

0 commit comments

Comments
 (0)