From 761c7e6751b98b859d6808649b6d1527124db7ea Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 5 Oct 2015 22:43:43 -0700 Subject: [PATCH] Optimize allocations for creating ActionConstraints --- .../DefaultActionConstraintProvider.cs | 4 +- .../ActionConstraints/HttpMethodConstraint.cs | 19 +++++--- .../Infrastructure/DefaultActionSelector.cs | 44 ++++++++++++++----- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionConstraints/DefaultActionConstraintProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ActionConstraints/DefaultActionConstraintProvider.cs index 1352424a5e..daff453263 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionConstraints/DefaultActionConstraintProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionConstraints/DefaultActionConstraintProvider.cs @@ -29,9 +29,9 @@ namespace Microsoft.AspNet.Mvc.ActionConstraints throw new ArgumentNullException(nameof(context)); } - foreach (var item in context.Results) + for (var i = 0; i < context.Results.Count; i++) { - ProvideConstraint(item, context.HttpContext.RequestServices); + ProvideConstraint(context.Results[i], context.HttpContext.RequestServices); } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionConstraints/HttpMethodConstraint.cs b/src/Microsoft.AspNet.Mvc.Core/ActionConstraints/HttpMethodConstraint.cs index 00912ab76b..3dc9143aca 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionConstraints/HttpMethodConstraint.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionConstraints/HttpMethodConstraint.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Mvc.ActionConstraints { public static readonly int HttpMethodConstraintOrder = 100; - private readonly IReadOnlyList _methods; + private readonly IReadOnlyList _httpMethods; private readonly string OriginHeader = "Origin"; private readonly string AccessControlRequestMethod = "Access-Control-Request-Method"; @@ -39,14 +39,14 @@ namespace Microsoft.AspNet.Mvc.ActionConstraints methods.Add(method); } - _methods = new ReadOnlyCollection(methods); + _httpMethods = new ReadOnlyCollection(methods); } public IEnumerable HttpMethods { get { - return _methods; + return _httpMethods; } } @@ -62,7 +62,7 @@ namespace Microsoft.AspNet.Mvc.ActionConstraints throw new ArgumentNullException(nameof(context)); } - if (_methods.Count == 0) + if (_httpMethods.Count == 0) { return true; } @@ -83,7 +83,16 @@ namespace Microsoft.AspNet.Mvc.ActionConstraints } } - return (HttpMethods.Any(m => m.Equals(method, StringComparison.Ordinal))); + for (var i = 0; i < _httpMethods.Count; i++) + { + var supportedMethod = _httpMethods[i]; + if (string.Equals(supportedMethod, method, StringComparison.Ordinal)) + { + return true; + } + } + + return false; } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/Infrastructure/DefaultActionSelector.cs b/src/Microsoft.AspNet.Mvc.Core/Infrastructure/DefaultActionSelector.cs index 1dfc1b3a38..e9c5c62d51 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Infrastructure/DefaultActionSelector.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Infrastructure/DefaultActionSelector.cs @@ -260,12 +260,16 @@ namespace Microsoft.AspNet.Mvc.Infrastructure return null; } - var items = action.ActionConstraints.Select(c => new ActionConstraintItem(c)).ToList(); - var context = new ActionConstraintProviderContext(httpContext, action, items); - - foreach (var provider in _actionConstraintProviders) + var items = new List(action.ActionConstraints.Count); + for (var i = 0; i < action.ActionConstraints.Count; i++) { - provider.OnProvidersExecuting(context); + items.Add(new ActionConstraintItem(action.ActionConstraints[i])); + } + + var context = new ActionConstraintProviderContext(httpContext, action, items); + for (var i = 0; i < _actionConstraintProviders.Length; i++) + { + _actionConstraintProviders[i].OnProvidersExecuting(context); } for (var i = _actionConstraintProviders.Length - 1; i >= 0; i--) @@ -273,11 +277,31 @@ namespace Microsoft.AspNet.Mvc.Infrastructure _actionConstraintProviders[i].OnProvidersExecuted(context); } - return - context.Results - .Where(item => item.Constraint != null) - .Select(item => item.Constraint) - .ToList(); + var count = 0; + for (var i = 0; i < context.Results.Count; i++) + { + if (context.Results[i].Constraint != null) + { + count++; + } + } + + if (count == 0) + { + return null; + } + + var results = new IActionConstraint[count]; + for (int i = 0, j = 0; i < context.Results.Count; i++) + { + var constraint = context.Results[i].Constraint; + if (constraint != null) + { + results[j++] = constraint; + } + } + + return results; } } }