Optimize allocations in GetFilters

Doing it the old fashioned way to get rid of some allocations.
This commit is contained in:
Ryan Nowak 2015-10-05 21:04:48 -07:00
parent e54da5e6f6
commit 082f175b48
1 changed files with 39 additions and 8 deletions

View File

@ -5,7 +5,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.Tracing; using System.Diagnostics.Tracing;
using System.Linq;
using System.Runtime.ExceptionServices; using System.Runtime.ExceptionServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Mvc.Abstractions;
@ -22,6 +21,8 @@ namespace Microsoft.AspNet.Mvc.Controllers
{ {
public abstract class FilterActionInvoker : IActionInvoker public abstract class FilterActionInvoker : IActionInvoker
{ {
private static readonly IFilterMetadata[] EmptyFilterArray = new IFilterMetadata[0];
private readonly IReadOnlyList<IFilterProvider> _filterProviders; private readonly IReadOnlyList<IFilterProvider> _filterProviders;
private readonly IReadOnlyList<IInputFormatter> _inputFormatters; private readonly IReadOnlyList<IInputFormatter> _inputFormatters;
private readonly IReadOnlyList<IModelBinder> _modelBinders; private readonly IReadOnlyList<IModelBinder> _modelBinders;
@ -223,13 +224,17 @@ namespace Microsoft.AspNet.Mvc.Controllers
private IFilterMetadata[] GetFilters() private IFilterMetadata[] GetFilters()
{ {
var context = new FilterProviderContext( var filterDescriptors = ActionContext.ActionDescriptor.FilterDescriptors;
ActionContext, var items = new List<FilterItem>(filterDescriptors.Count);
ActionContext.ActionDescriptor.FilterDescriptors.Select(fd => new FilterItem(fd)).ToList()); for (var i = 0; i < filterDescriptors.Count; i++)
foreach (var provider in _filterProviders)
{ {
provider.OnProvidersExecuting(context); items.Add(new FilterItem(filterDescriptors[i]));
}
var context = new FilterProviderContext(ActionContext, items);
for (var i = 0; i < _filterProviders.Count; i++)
{
_filterProviders[i].OnProvidersExecuting(context);
} }
for (var i = _filterProviders.Count - 1; i >= 0; i--) for (var i = _filterProviders.Count - 1; i >= 0; i--)
@ -237,7 +242,33 @@ namespace Microsoft.AspNet.Mvc.Controllers
_filterProviders[i].OnProvidersExecuted(context); _filterProviders[i].OnProvidersExecuted(context);
} }
return context.Results.Select(item => item.Filter).Where(filter => filter != null).ToArray(); var count = 0;
for (var i = 0; i < items.Count; i++)
{
if (items[i].Filter != null)
{
count++;
}
}
if (count == 0)
{
return EmptyFilterArray;
}
else
{
var filters = new IFilterMetadata[count];
for (int i = 0, j = 0; i < items.Count; i++)
{
var filter = items[i].Filter;
if (filter != null)
{
filters[j++] = filter;
}
}
return filters;
}
} }
private Task InvokeAllAuthorizationFiltersAsync() private Task InvokeAllAuthorizationFiltersAsync()