[Perf] Reduce allocations in Link generation code paths
This commit is contained in:
parent
a80a63271f
commit
1c9a54aeb8
|
|
@ -22,10 +22,16 @@ namespace Microsoft.AspNetCore.Routing.Internal
|
||||||
|
|
||||||
public IList<LinkGenerationMatch> GetMatches(VirtualPathContext context)
|
public IList<LinkGenerationMatch> GetMatches(VirtualPathContext context)
|
||||||
{
|
{
|
||||||
var results = new List<LinkGenerationMatch>();
|
// Perf: Avoid allocation for List if there aren't any Matches or Criteria
|
||||||
Walk(results, context, _root, isFallbackPath: false);
|
if (_root.Matches.Count > 0 || _root.Criteria.Count > 0)
|
||||||
results.Sort(LinkGenerationMatchComparer.Instance);
|
{
|
||||||
return results;
|
var results = new List<LinkGenerationMatch>();
|
||||||
|
Walk(results, context, _root, isFallbackPath: false);
|
||||||
|
results.Sort(LinkGenerationMatchComparer.Instance);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to recursively walk the decision tree based on the provided route data
|
// We need to recursively walk the decision tree based on the provided route data
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
throw new ArgumentNullException(nameof(logger));
|
throw new ArgumentNullException(nameof(logger));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constraints == null)
|
if (constraints == null || constraints.Count == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,8 @@ namespace Microsoft.AspNetCore.Routing.Template
|
||||||
|
|
||||||
// Add any ambient values that don't match parameters - they need to be visible to constraints
|
// Add any ambient values that don't match parameters - they need to be visible to constraints
|
||||||
// but they will ignored by link generation.
|
// but they will ignored by link generation.
|
||||||
var combinedValues = new RouteValueDictionary(context.AcceptedValues);
|
// Perf: Lazily allocate RouteValueDictionary only when needed as in most cases combined is same as accepted values
|
||||||
|
RouteValueDictionary combinedValues = null;
|
||||||
if (ambientValues != null)
|
if (ambientValues != null)
|
||||||
{
|
{
|
||||||
foreach (var kvp in ambientValues)
|
foreach (var kvp in ambientValues)
|
||||||
|
|
@ -181,6 +182,10 @@ namespace Microsoft.AspNetCore.Routing.Template
|
||||||
var parameter = GetParameter(kvp.Key);
|
var parameter = GetParameter(kvp.Key);
|
||||||
if (parameter == null && !context.AcceptedValues.ContainsKey(kvp.Key))
|
if (parameter == null && !context.AcceptedValues.ContainsKey(kvp.Key))
|
||||||
{
|
{
|
||||||
|
if (combinedValues == null)
|
||||||
|
{
|
||||||
|
combinedValues = new RouteValueDictionary(context.AcceptedValues);
|
||||||
|
}
|
||||||
combinedValues.Add(kvp.Key, kvp.Value);
|
combinedValues.Add(kvp.Key, kvp.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +195,7 @@ namespace Microsoft.AspNetCore.Routing.Template
|
||||||
return new TemplateValuesResult()
|
return new TemplateValuesResult()
|
||||||
{
|
{
|
||||||
AcceptedValues = context.AcceptedValues,
|
AcceptedValues = context.AcceptedValues,
|
||||||
CombinedValues = combinedValues,
|
CombinedValues = combinedValues ?? context.AcceptedValues
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,9 +138,14 @@ namespace Microsoft.AspNetCore.Routing.Tree
|
||||||
// order. We just need to iterate them and use the first one that can generate a link.
|
// order. We just need to iterate them and use the first one that can generate a link.
|
||||||
var matches = _linkGenerationTree.GetMatches(context);
|
var matches = _linkGenerationTree.GetMatches(context);
|
||||||
|
|
||||||
foreach (var match in matches)
|
if (matches == null)
|
||||||
{
|
{
|
||||||
var path = GenerateVirtualPath(context, match.Entry);
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < matches.Count; i++)
|
||||||
|
{
|
||||||
|
var path = GenerateVirtualPath(context, matches[i].Entry);
|
||||||
if (path != null)
|
if (path != null)
|
||||||
{
|
{
|
||||||
return path;
|
return path;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue