[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)
|
||||
{
|
||||
var results = new List<LinkGenerationMatch>();
|
||||
Walk(results, context, _root, isFallbackPath: false);
|
||||
results.Sort(LinkGenerationMatchComparer.Instance);
|
||||
return results;
|
||||
// Perf: Avoid allocation for List if there aren't any Matches or Criteria
|
||||
if (_root.Matches.Count > 0 || _root.Criteria.Count > 0)
|
||||
{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
if (constraints == null)
|
||||
if (constraints == null || constraints.Count == 0)
|
||||
{
|
||||
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
|
||||
// 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)
|
||||
{
|
||||
foreach (var kvp in ambientValues)
|
||||
|
|
@ -181,6 +182,10 @@ namespace Microsoft.AspNetCore.Routing.Template
|
|||
var parameter = GetParameter(kvp.Key);
|
||||
if (parameter == null && !context.AcceptedValues.ContainsKey(kvp.Key))
|
||||
{
|
||||
if (combinedValues == null)
|
||||
{
|
||||
combinedValues = new RouteValueDictionary(context.AcceptedValues);
|
||||
}
|
||||
combinedValues.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
|
@ -190,7 +195,7 @@ namespace Microsoft.AspNetCore.Routing.Template
|
|||
return new TemplateValuesResult()
|
||||
{
|
||||
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.
|
||||
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)
|
||||
{
|
||||
return path;
|
||||
|
|
|
|||
Loading…
Reference in New Issue