Optimize RoutePattern allocations (#706)

This commit is contained in:
James Newton-King 2018-08-22 10:01:52 +12:00 committed by GitHub
parent 4a064b2267
commit 967afc3b0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 11 deletions

View File

@ -21,10 +21,10 @@ namespace Microsoft.AspNetCore.Routing.Patterns
internal RoutePattern(
string rawText,
Dictionary<string, object> defaults,
Dictionary<string, IReadOnlyList<RoutePatternConstraintReference>> constraints,
RoutePatternParameterPart[] parameters,
RoutePatternPathSegment[] pathSegments)
IReadOnlyDictionary<string, object> defaults,
IReadOnlyDictionary<string, IReadOnlyList<RoutePatternConstraintReference>> constraints,
IReadOnlyList<RoutePatternParameterPart> parameters,
IReadOnlyList<RoutePatternPathSegment> pathSegments)
{
Debug.Assert(defaults != null);
Debug.Assert(constraints != null);

View File

@ -298,19 +298,35 @@ namespace Microsoft.AspNetCore.Routing.Patterns
rawText,
updatedDefaults,
updatedConstraints.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList<RoutePatternConstraintReference>)kvp.Value.ToArray()),
parameters.ToArray(),
updatedSegments.ToArray());
parameters,
updatedSegments);
RoutePatternPathSegment VisitSegment(RoutePatternPathSegment segment)
{
var updatedParts = new RoutePatternPart[segment.Parts.Count];
RoutePatternPart[] updatedParts = null;
for (var i = 0; i < segment.Parts.Count; i++)
{
var part = segment.Parts[i];
updatedParts[i] = VisitPart(part);
var updatedPart = VisitPart(part);
if (part != updatedPart)
{
if (updatedParts == null)
{
updatedParts = segment.Parts.ToArray();
}
updatedParts[i] = updatedPart;
}
}
return SegmentCore(updatedParts);
if (updatedParts == null)
{
// Segment has not changed
return segment;
}
return new RoutePatternPathSegment(updatedParts);
}
RoutePatternPart VisitPart(RoutePatternPart part)
@ -357,6 +373,14 @@ namespace Microsoft.AspNetCore.Routing.Patterns
parameterConstraints.AddRange(parameter.Constraints);
}
if (Equals(parameter.Default, @default)
&& parameter.Constraints.Count == 0
&& (parameterConstraints?.Count ?? 0) == 0)
{
// Part has not changed
return part;
}
return ParameterPartCore(
parameter.Name,
@default,

View File

@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
if (IsSegmentValid(context, parts))
{
segments.Add(new RoutePatternPathSegment(parts.ToArray()));
segments.Add(new RoutePatternPathSegment(parts));
return true;
}
else

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
[DebuggerDisplay("{DebuggerToString()}")]
public sealed class RoutePatternPathSegment
{
internal RoutePatternPathSegment(RoutePatternPart[] parts)
internal RoutePatternPathSegment(IReadOnlyList<RoutePatternPart> parts)
{
Parts = parts;
}