From 082f175b4875292751a1470738896e96c857ebc9 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 5 Oct 2015 21:04:48 -0700 Subject: [PATCH] Optimize allocations in GetFilters Doing it the old fashioned way to get rid of some allocations. --- .../Controllers/FilterActionInvoker.cs | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.AspNet.Mvc.Core/Controllers/FilterActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/Controllers/FilterActionInvoker.cs index de182a9a19..13b4159b62 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Controllers/FilterActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Controllers/FilterActionInvoker.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Tracing; -using System.Linq; using System.Runtime.ExceptionServices; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Abstractions; @@ -22,6 +21,8 @@ namespace Microsoft.AspNet.Mvc.Controllers { public abstract class FilterActionInvoker : IActionInvoker { + private static readonly IFilterMetadata[] EmptyFilterArray = new IFilterMetadata[0]; + private readonly IReadOnlyList _filterProviders; private readonly IReadOnlyList _inputFormatters; private readonly IReadOnlyList _modelBinders; @@ -223,13 +224,17 @@ namespace Microsoft.AspNet.Mvc.Controllers private IFilterMetadata[] GetFilters() { - var context = new FilterProviderContext( - ActionContext, - ActionContext.ActionDescriptor.FilterDescriptors.Select(fd => new FilterItem(fd)).ToList()); - - foreach (var provider in _filterProviders) + var filterDescriptors = ActionContext.ActionDescriptor.FilterDescriptors; + var items = new List(filterDescriptors.Count); + for (var i = 0; i < filterDescriptors.Count; i++) { - 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--) @@ -237,7 +242,33 @@ namespace Microsoft.AspNet.Mvc.Controllers _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()