Improve performance and reduce allocations in DecisionTreeBuilder<T>.
This commit is contained in:
parent
29b50c7b64
commit
3c9086e3d0
|
|
@ -74,14 +74,16 @@ namespace Microsoft.AspNetCore.Routing.DecisionTree
|
||||||
{
|
{
|
||||||
public static DecisionTreeNode<TItem> GenerateTree(IReadOnlyList<TItem> items, IClassifier<TItem> classifier)
|
public static DecisionTreeNode<TItem> GenerateTree(IReadOnlyList<TItem> items, IClassifier<TItem> classifier)
|
||||||
{
|
{
|
||||||
var itemDescriptors = new List<ItemDescriptor<TItem>>();
|
var itemCount = items.Count;
|
||||||
for (var i = 0; i < items.Count; i++)
|
var itemDescriptors = new List<ItemDescriptor<TItem>>(itemCount);
|
||||||
|
for (var i = 0; i < itemCount; i++)
|
||||||
{
|
{
|
||||||
|
var item = items[i];
|
||||||
itemDescriptors.Add(new ItemDescriptor<TItem>()
|
itemDescriptors.Add(new ItemDescriptor<TItem>()
|
||||||
{
|
{
|
||||||
Criteria = classifier.GetCriteria(items[i]),
|
Criteria = classifier.GetCriteria(item),
|
||||||
Index = i,
|
Index = i,
|
||||||
Item = items[i],
|
Item = item,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,7 +97,7 @@ namespace Microsoft.AspNetCore.Routing.DecisionTree
|
||||||
private static DecisionTreeNode<TItem> GenerateNode(
|
private static DecisionTreeNode<TItem> GenerateNode(
|
||||||
TreeBuilderContext context,
|
TreeBuilderContext context,
|
||||||
DecisionCriterionValueEqualityComparer comparer,
|
DecisionCriterionValueEqualityComparer comparer,
|
||||||
IList<ItemDescriptor<TItem>> items)
|
List<ItemDescriptor<TItem>> items)
|
||||||
{
|
{
|
||||||
// The extreme use of generics here is intended to reduce the number of intermediate
|
// The extreme use of generics here is intended to reduce the number of intermediate
|
||||||
// allocations of wrapper classes. Performance testing found that building these trees allocates
|
// allocations of wrapper classes. Performance testing found that building these trees allocates
|
||||||
|
|
@ -156,16 +158,17 @@ namespace Microsoft.AspNetCore.Routing.DecisionTree
|
||||||
|
|
||||||
foreach (var branch in criterion.Value)
|
foreach (var branch in criterion.Value)
|
||||||
{
|
{
|
||||||
var reducedItems = new List<ItemDescriptor<TItem>>();
|
bool hasReducedItems = false;
|
||||||
|
|
||||||
foreach (var item in branch.Value)
|
foreach (var item in branch.Value)
|
||||||
{
|
{
|
||||||
if (context.MatchedItems.Add(item))
|
if (context.MatchedItems.Add(item))
|
||||||
{
|
{
|
||||||
reducedItems.Add(item);
|
hasReducedItems = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reducedItems.Count > 0)
|
if (hasReducedItems)
|
||||||
{
|
{
|
||||||
var childContext = new TreeBuilderContext(context);
|
var childContext = new TreeBuilderContext(context);
|
||||||
childContext.CurrentCriteria.Add(criterion.Key);
|
childContext.CurrentCriteria.Add(criterion.Key);
|
||||||
|
|
@ -189,7 +192,7 @@ namespace Microsoft.AspNetCore.Routing.DecisionTree
|
||||||
|
|
||||||
return new DecisionTreeNode<TItem>()
|
return new DecisionTreeNode<TItem>()
|
||||||
{
|
{
|
||||||
Criteria = reducedCriteria.ToList(),
|
Criteria = reducedCriteria,
|
||||||
Matches = matches,
|
Matches = matches,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue