Optimizing TagBuilder.CreateSanitizedId to create buffer only when needed.
- Tested with a page containing 33% of invalid Ids which go through TagBuilder.CreateSanitizedId. - Ran 10,000 requests with 20 in parallel and measured perf. - Data before the change: System.String allocated by CreateSanitizedId: 1.84 mb System.Text.StringBuilder allocated by CreateSanitizedId: 1.68 mb - Data after the change: System.String allocated by CreateSanitizedId: 0.720 mb System.Text.StringBuilder allocated by CreateSanitizedId: 0.560 mb Around 60% improvement from the original case.
This commit is contained in:
parent
4b18bfb494
commit
57f1ae755f
|
|
@ -77,16 +77,40 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
return string.Empty;
|
||||
}
|
||||
|
||||
// If there are no invalid characters in the string, then we don't have to create the buffer.
|
||||
var firstIndexOfInvalidCharacter = 1;
|
||||
for (; firstIndexOfInvalidCharacter < name.Length; firstIndexOfInvalidCharacter++)
|
||||
{
|
||||
if (!Html401IdUtil.IsValidIdCharacter(name[firstIndexOfInvalidCharacter]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var firstChar = name[0];
|
||||
if (!Html401IdUtil.IsAsciiLetter(firstChar))
|
||||
var startsWithAsciiLetter = Html401IdUtil.IsAsciiLetter(firstChar);
|
||||
if (!startsWithAsciiLetter)
|
||||
{
|
||||
// The first character must be a letter according to the HTML 4.01 specification.
|
||||
firstChar = 'z';
|
||||
}
|
||||
|
||||
if (firstIndexOfInvalidCharacter == name.Length && startsWithAsciiLetter)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
var stringBuffer = new StringBuilder(name.Length);
|
||||
stringBuffer.Append(firstChar);
|
||||
for (var index = 1; index < name.Length; index++)
|
||||
|
||||
// Characters until 'firstIndexOfInvalidCharacter' have already been checked for validity.
|
||||
// So just copying them. This avoids running them through Html401IdUtil.IsValidIdCharacter again.
|
||||
for (var index = 1; index < firstIndexOfInvalidCharacter; index++)
|
||||
{
|
||||
stringBuffer.Append(name[index]);
|
||||
}
|
||||
|
||||
for (var index = firstIndexOfInvalidCharacter; index < name.Length; index++)
|
||||
{
|
||||
var thisChar = name[index];
|
||||
if (Html401IdUtil.IsValidIdCharacter(thisChar))
|
||||
|
|
|
|||
|
|
@ -116,5 +116,18 @@ namespace Microsoft.AspNet.Mvc.Core.Rendering
|
|||
// Assert
|
||||
Assert.Equal("HtmlEncode[[TestValue]]", tagBuilder.InnerHtml);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("HelloWorld", "HelloWorld")]
|
||||
[InlineData("¡HelloWorld", "zHelloWorld")]
|
||||
[InlineData("Hello¡World", "Hello-World")]
|
||||
public void CreateSanitizedIdCreatesId(string input, string output)
|
||||
{
|
||||
// Arrange
|
||||
var result = TagBuilder.CreateSanitizedId(input, "-");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(output, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue