[Perf] Reduce allocations in Link generation code paths

This commit is contained in:
mnltejaswini 2016-02-24 17:25:32 -08:00
parent a80a63271f
commit 1c9a54aeb8
4 changed files with 25 additions and 9 deletions

View File

@ -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

View File

@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Routing
throw new ArgumentNullException(nameof(logger));
}
if (constraints == null)
if (constraints == null || constraints.Count == 0)
{
return true;
}

View File

@ -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
};
}

View File

@ -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;