From b22512de0e5d7bda763351cfbce1fce7898d07b6 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 19 Aug 2020 17:45:52 +0100 Subject: [PATCH] Right-size Lists when created (#23714) Create new instances of List with an appropriate capacity for the items that will be added. Use Array.Empty() where appropriate, rather than create an empty list and then return it. --- .../src/Manifest/ManifestDirectory.cs | 2 +- .../src/Features/RequestCookiesFeature.cs | 2 +- .../src/Patterns/RoutePatternFactory.cs | 2 +- src/Identity/Core/src/SignInManager.cs | 23 ++++++++++++------- .../src/RequestLocalizationOptions.cs | 4 ++-- .../ApplicationModelFactory.cs | 2 +- .../ControllerActionDescriptorBuilder.cs | 2 +- .../DefaultApplicationModelProvider.cs | 2 +- src/Mvc/Mvc.Core/src/BindAttribute.cs | 2 +- src/Mvc/Mvc.Core/src/ConsumesAttribute.cs | 2 +- .../Mvc.Core/src/Formatters/InputFormatter.cs | 2 +- .../src/Formatters/OutputFormatter.cs | 4 ++-- .../src/Infrastructure/ActionSelector.cs | 10 ++++---- src/Mvc/Mvc.Core/src/ProducesAttribute.cs | 2 +- .../src/RazorReferenceManager.cs | 2 +- .../DefaultTempDataSerializer.cs | 7 +++--- .../ComponentEventHandlerLoweringPass.cs | 2 +- .../src/Application.cs | 2 +- .../src/DefaultRequestDispatcher.cs | 2 +- .../src/MetadataReaderExtensions.cs | 2 +- .../src/FindAssembliesWithReferencesTo.cs | 2 +- .../src/ReferenceResolver.cs | 2 +- .../ReadOnlyTagHelperAttributeList.cs | 6 ++--- .../ReadOnlyTagHelperAttributeList.cs | 4 +--- .../src/CertificateAuthenticationHandler.cs | 2 +- .../JwtBearer/src/JwtBearerHandler.cs | 4 ++-- .../HttpSys/src/AuthenticationManager.cs | 6 ++--- src/Servers/HttpSys/src/HttpSysListener.cs | 2 +- .../ReadOnlySequenceFactory.cs | 2 +- .../ObjectMethodExecutor.cs | 4 ++-- .../StackTrace/StackFrame/StackTraceHelper.cs | 8 +++---- .../src/Internal/HttpConnectionManager.cs | 2 +- .../server/Core/src/HubConnectionHandler.cs | 6 ++--- .../server/Core/src/HubOptionsSetup.cs | 2 +- .../Internal/DefaultHubMessageSerializer.cs | 3 ++- .../src/RedisHubLifetimeManager.cs | 4 ++-- 36 files changed, 71 insertions(+), 66 deletions(-) diff --git a/src/FileProviders/Embedded/src/Manifest/ManifestDirectory.cs b/src/FileProviders/Embedded/src/Manifest/ManifestDirectory.cs index b75653a0fb..3aa2429ad6 100644 --- a/src/FileProviders/Embedded/src/Manifest/ManifestDirectory.cs +++ b/src/FileProviders/Embedded/src/Manifest/ManifestDirectory.cs @@ -98,7 +98,7 @@ namespace Microsoft.Extensions.FileProviders.Embedded.Manifest private ManifestEntry[] CopyChildren() { - var list = new List(); + var list = new List(Children.Count); for (int i = 0; i < Children.Count; i++) { var child = Children[i]; diff --git a/src/Http/Http/src/Features/RequestCookiesFeature.cs b/src/Http/Http/src/Features/RequestCookiesFeature.cs index a89bb99f5d..b0698ecdca 100644 --- a/src/Http/Http/src/Features/RequestCookiesFeature.cs +++ b/src/Http/Http/src/Features/RequestCookiesFeature.cs @@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Http.Features } else { - var headers = new List(); + var headers = new List(_parsedValues.Count); foreach (var pair in _parsedValues) { headers.Add(new CookieHeaderValue(pair.Key, pair.Value).ToString()); diff --git a/src/Http/Routing/src/Patterns/RoutePatternFactory.cs b/src/Http/Routing/src/Patterns/RoutePatternFactory.cs index 8832e94e59..9534ba6f6f 100644 --- a/src/Http/Routing/src/Patterns/RoutePatternFactory.cs +++ b/src/Http/Routing/src/Patterns/RoutePatternFactory.cs @@ -497,7 +497,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns updatedParameterPolicies = new Dictionary>(StringComparer.OrdinalIgnoreCase); } - parameterConstraints = new List(); + parameterConstraints = new List(parameter.ParameterPolicies.Count); updatedParameterPolicies.Add(parameter.Name, parameterConstraints); } diff --git a/src/Identity/Core/src/SignInManager.cs b/src/Identity/Core/src/SignInManager.cs index f523b3319b..32ad02a16d 100644 --- a/src/Identity/Core/src/SignInManager.cs +++ b/src/Identity/Core/src/SignInManager.cs @@ -169,16 +169,22 @@ namespace Microsoft.AspNetCore.Identity public virtual async Task RefreshSignInAsync(TUser user) { var auth = await Context.AuthenticateAsync(IdentityConstants.ApplicationScheme); - var claims = new List(); + IList claims = Array.Empty(); + var authenticationMethod = auth?.Principal?.FindFirst(ClaimTypes.AuthenticationMethod); - if (authenticationMethod != null) - { - claims.Add(authenticationMethod); - } var amr = auth?.Principal?.FindFirst("amr"); - if (amr != null) + + if (authenticationMethod != null || amr != null) { - claims.Add(amr); + claims = new List(); + if (authenticationMethod != null) + { + claims.Add(authenticationMethod); + } + if (amr != null) + { + claims.Add(amr); + } } await SignInWithClaimsAsync(user, auth?.Properties, claims); @@ -203,9 +209,10 @@ namespace Microsoft.AspNetCore.Identity /// The task object representing the asynchronous operation. public virtual Task SignInAsync(TUser user, AuthenticationProperties authenticationProperties, string authenticationMethod = null) { - var additionalClaims = new List(); + IList additionalClaims = Array.Empty(); if (authenticationMethod != null) { + additionalClaims = new List(); additionalClaims.Add(new Claim(ClaimTypes.AuthenticationMethod, authenticationMethod)); } return SignInWithClaimsAsync(user, authenticationProperties, additionalClaims); diff --git a/src/Middleware/Localization/src/RequestLocalizationOptions.cs b/src/Middleware/Localization/src/RequestLocalizationOptions.cs index 95ca74fe32..c77c10dfe5 100644 --- a/src/Middleware/Localization/src/RequestLocalizationOptions.cs +++ b/src/Middleware/Localization/src/RequestLocalizationOptions.cs @@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Builder /// The . public RequestLocalizationOptions AddSupportedCultures(params string[] cultures) { - var supportedCultures = new List(); + var supportedCultures = new List(cultures.Length); foreach (var culture in cultures) { @@ -140,7 +140,7 @@ namespace Microsoft.AspNetCore.Builder /// The . public RequestLocalizationOptions AddSupportedUICultures(params string[] uiCultures) { - var supportedUICultures = new List(); + var supportedUICultures = new List(uiCultures.Length); foreach (var culture in uiCultures) { supportedUICultures.Add(new CultureInfo(culture)); diff --git a/src/Mvc/Mvc.Core/src/ApplicationModels/ApplicationModelFactory.cs b/src/Mvc/Mvc.Core/src/ApplicationModels/ApplicationModelFactory.cs index 88f8ce93f4..842292f476 100644 --- a/src/Mvc/Mvc.Core/src/ApplicationModels/ApplicationModelFactory.cs +++ b/src/Mvc/Mvc.Core/src/ApplicationModels/ApplicationModelFactory.cs @@ -309,7 +309,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels // Text to show as the attribute route template for conventionally routed actions. var nullTemplate = Resources.AttributeRoute_NullTemplateRepresentation; - var actionDescriptions = new List(); + var actionDescriptions = new List(actions.Count); for (var i = 0; i < actions.Count; i++) { var (action, selector) = actions[i]; diff --git a/src/Mvc/Mvc.Core/src/ApplicationModels/ControllerActionDescriptorBuilder.cs b/src/Mvc/Mvc.Core/src/ApplicationModels/ControllerActionDescriptorBuilder.cs index c53234af3e..9b2e8a951a 100644 --- a/src/Mvc/Mvc.Core/src/ApplicationModels/ControllerActionDescriptorBuilder.cs +++ b/src/Mvc/Mvc.Core/src/ApplicationModels/ControllerActionDescriptorBuilder.cs @@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels private static void AddParameterDescriptors(ActionDescriptor actionDescriptor, ActionModel action) { - var parameterDescriptors = new List(); + var parameterDescriptors = new List(action.Parameters.Count); foreach (var parameter in action.Parameters) { var parameterDescriptor = CreateParameterDescriptor(parameter); diff --git a/src/Mvc/Mvc.Core/src/ApplicationModels/DefaultApplicationModelProvider.cs b/src/Mvc/Mvc.Core/src/ApplicationModels/DefaultApplicationModelProvider.cs index 3171c8f1ab..f309c37ccc 100644 --- a/src/Mvc/Mvc.Core/src/ApplicationModels/DefaultApplicationModelProvider.cs +++ b/src/Mvc/Mvc.Core/src/ApplicationModels/DefaultApplicationModelProvider.cs @@ -352,7 +352,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels // This is fairly complicated so that we maintain referential equality between items in // ActionModel.Attributes and ActionModel.Attributes[*].Attribute. - var applicableAttributes = new List(); + var applicableAttributes = new List(routeAttributes.Length); foreach (var attribute in attributes) { if (attribute is IRouteTemplateProvider) diff --git a/src/Mvc/Mvc.Core/src/BindAttribute.cs b/src/Mvc/Mvc.Core/src/BindAttribute.cs index 691c81ac7c..e4f1ab2bc7 100644 --- a/src/Mvc/Mvc.Core/src/BindAttribute.cs +++ b/src/Mvc/Mvc.Core/src/BindAttribute.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Mvc /// Names of parameters to include in binding. public BindAttribute(params string[] include) { - var items = new List(); + var items = new List(include.Length); foreach (var item in include) { items.AddRange(SplitString(item)); diff --git a/src/Mvc/Mvc.Core/src/ConsumesAttribute.cs b/src/Mvc/Mvc.Core/src/ConsumesAttribute.cs index 12afb98c32..14bcf68626 100644 --- a/src/Mvc/Mvc.Core/src/ConsumesAttribute.cs +++ b/src/Mvc/Mvc.Core/src/ConsumesAttribute.cs @@ -199,7 +199,7 @@ namespace Microsoft.AspNetCore.Mvc private MediaTypeCollection GetContentTypes(string firstArg, string[] args) { - var completeArgs = new List(); + var completeArgs = new List(args.Length + 1); completeArgs.Add(firstArg); completeArgs.AddRange(args); var contentTypes = new MediaTypeCollection(); diff --git a/src/Mvc/Mvc.Core/src/Formatters/InputFormatter.cs b/src/Mvc/Mvc.Core/src/Formatters/InputFormatter.cs index 2392b5a47c..93fac14855 100644 --- a/src/Mvc/Mvc.Core/src/Formatters/InputFormatter.cs +++ b/src/Mvc/Mvc.Core/src/Formatters/InputFormatter.cs @@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters { if (mediaTypes == null) { - mediaTypes = new List(); + mediaTypes = new List(SupportedMediaTypes.Count); } mediaTypes.Add(mediaType); diff --git a/src/Mvc/Mvc.Core/src/Formatters/OutputFormatter.cs b/src/Mvc/Mvc.Core/src/Formatters/OutputFormatter.cs index fd0c37b972..53cfa8706a 100644 --- a/src/Mvc/Mvc.Core/src/Formatters/OutputFormatter.cs +++ b/src/Mvc/Mvc.Core/src/Formatters/OutputFormatter.cs @@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters { if (mediaTypes == null) { - mediaTypes = new List(); + mediaTypes = new List(SupportedMediaTypes.Count); } mediaTypes.Add(contentType); @@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters { if (mediaTypes == null) { - mediaTypes = new List(); + mediaTypes = new List(SupportedMediaTypes.Count); } mediaTypes.Add(mediaType); diff --git a/src/Mvc/Mvc.Core/src/Infrastructure/ActionSelector.cs b/src/Mvc/Mvc.Core/src/Infrastructure/ActionSelector.cs index 2912f9ec85..72600a980c 100644 --- a/src/Mvc/Mvc.Core/src/Infrastructure/ActionSelector.cs +++ b/src/Mvc/Mvc.Core/src/Infrastructure/ActionSelector.cs @@ -135,10 +135,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure RouteContext context, IReadOnlyList actions) { - var candidates = new List(); + var actionsCount = actions.Count; + var candidates = new List(actionsCount); // Perf: Avoid allocations - for (var i = 0; i < actions.Count; i++) + for (var i = 0; i < actionsCount; i++) { var action = actions[i]; var constraints = _actionConstraintCache.GetActionConstraints(context.HttpContext, action); @@ -150,9 +151,10 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure List results = null; if (matches != null) { - results = new List(matches.Count); + var matchesCount = matches.Count; + results = new List(matchesCount); // Perf: Avoid allocations - for (var i = 0; i < matches.Count; i++) + for (var i = 0; i < matchesCount; i++) { var candidate = matches[i]; results.Add(candidate.Action); diff --git a/src/Mvc/Mvc.Core/src/ProducesAttribute.cs b/src/Mvc/Mvc.Core/src/ProducesAttribute.cs index 24218189e5..aa0429cc79 100644 --- a/src/Mvc/Mvc.Core/src/ProducesAttribute.cs +++ b/src/Mvc/Mvc.Core/src/ProducesAttribute.cs @@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Mvc private MediaTypeCollection GetContentTypes(string firstArg, string[] args) { - var completeArgs = new List(); + var completeArgs = new List(args.Length + 1); completeArgs.Add(firstArg); completeArgs.AddRange(args); var contentTypes = new MediaTypeCollection(); diff --git a/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorReferenceManager.cs b/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorReferenceManager.cs index b672dbaff6..99151aea0e 100644 --- a/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorReferenceManager.cs +++ b/src/Mvc/Mvc.Razor.RuntimeCompilation/src/RazorReferenceManager.cs @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation // For unit testing internal IEnumerable GetReferencePaths() { - var referencePaths = new List(); + var referencePaths = new List(_options.AdditionalReferencePaths.Count); foreach (var part in _partManager.ApplicationParts) { diff --git a/src/Mvc/Mvc.ViewFeatures/src/Infrastructure/DefaultTempDataSerializer.cs b/src/Mvc/Mvc.ViewFeatures/src/Infrastructure/DefaultTempDataSerializer.cs index 4ca26e540a..2f2af39b1b 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/Infrastructure/DefaultTempDataSerializer.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/Infrastructure/DefaultTempDataSerializer.cs @@ -83,7 +83,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure private static object DeserializeArray(in JsonElement arrayElement) { - if (arrayElement.GetArrayLength() == 0) + int arrayLength = arrayElement.GetArrayLength(); + if (arrayLength == 0) { // We have to infer the type of the array by inspecting it's elements. // If there's nothing to inspect, return a null value since we do not know @@ -93,7 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure if (arrayElement[0].ValueKind == JsonValueKind.String) { - var array = new List(); + var array = new List(arrayLength); foreach (var item in arrayElement.EnumerateArray()) { @@ -104,7 +105,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure } else if (arrayElement[0].ValueKind == JsonValueKind.Number) { - var array = new List(); + var array = new List(arrayLength); foreach (var item in arrayElement.EnumerateArray()) { diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentEventHandlerLoweringPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentEventHandlerLoweringPass.cs index 2e72dfe397..dd6a18e5e3 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentEventHandlerLoweringPass.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentEventHandlerLoweringPass.cs @@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components // This method is overloaded on string and T, which means that it will put the code in the // correct context for intellisense when typing in the attribute. var eventArgsType = node.TagHelper.GetEventArgsType(); - var tokens = new List() + var tokens = new List(original.Count + 2) { new IntermediateToken() { diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Application.cs b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Application.cs index de4870f823..0d03cba384 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Application.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/Application.cs @@ -96,7 +96,7 @@ namespace Microsoft.AspNetCore.Razor.Tools private static string[] ExpandResponseFiles(string[] args) { - var expandedArgs = new List(); + var expandedArgs = new List(args.Length); foreach (var arg in args) { if (!arg.StartsWith("@", StringComparison.Ordinal)) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/DefaultRequestDispatcher.cs b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/DefaultRequestDispatcher.cs index 59d2bbc098..110494b249 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/DefaultRequestDispatcher.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/DefaultRequestDispatcher.cs @@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.Razor.Tools /// private void WaitForAnyCompletion(CancellationToken cancellationToken) { - var all = new List(); + var all = new List(_connections.Count + 3); all.AddRange(_connections); all.Add(_timeoutTask); all.Add(_listenTask); diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/MetadataReaderExtensions.cs b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/MetadataReaderExtensions.cs index 17da6b63be..7becdaca41 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/MetadataReaderExtensions.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Tools/src/MetadataReaderExtensions.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Razor.Tools internal static AssemblyIdentity[] GetReferencedAssembliesOrThrow(this MetadataReader reader) { - var references = new List(); + var references = new List(reader.AssemblyReferences.Count); foreach (var referenceHandle in reader.AssemblyReferences) { diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/FindAssembliesWithReferencesTo.cs b/src/Razor/Microsoft.NET.Sdk.Razor/src/FindAssembliesWithReferencesTo.cs index cb1d2359e8..b9e03c0791 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/FindAssembliesWithReferencesTo.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/FindAssembliesWithReferencesTo.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Tasks public override bool Execute() { - var referenceItems = new List(); + var referenceItems = new List(Assemblies.Length); foreach (var item in Assemblies) { const string FusionNameKey = "FusionName"; diff --git a/src/Razor/Microsoft.NET.Sdk.Razor/src/ReferenceResolver.cs b/src/Razor/Microsoft.NET.Sdk.Razor/src/ReferenceResolver.cs index 6b1489cab0..c259b70a83 100644 --- a/src/Razor/Microsoft.NET.Sdk.Razor/src/ReferenceResolver.cs +++ b/src/Razor/Microsoft.NET.Sdk.Razor/src/ReferenceResolver.cs @@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Razor.Tasks var metadataReader = peReader.GetMetadataReader(); - var references = new List(); + var references = new List(metadataReader.AssemblyReferences.Count); foreach (var handle in metadataReader.AssemblyReferences) { var reference = metadataReader.GetAssemblyReference(handle); diff --git a/src/Razor/Razor/src/TagHelpers/ReadOnlyTagHelperAttributeList.cs b/src/Razor/Razor/src/TagHelpers/ReadOnlyTagHelperAttributeList.cs index 2b0b55d1f1..376b210816 100644 --- a/src/Razor/Razor/src/TagHelpers/ReadOnlyTagHelperAttributeList.cs +++ b/src/Razor/Razor/src/TagHelpers/ReadOnlyTagHelperAttributeList.cs @@ -12,8 +12,6 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers /// public abstract class ReadOnlyTagHelperAttributeList : ReadOnlyCollection { - private static readonly IReadOnlyList EmptyList = new TagHelperAttribute[0]; - /// /// Instantiates a new instance of with an empty /// collection. @@ -146,7 +144,7 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers matchedAttributes.Add(attribute); } } - attributes = matchedAttributes ?? EmptyList; + attributes = matchedAttributes ?? (IReadOnlyList)Array.Empty(); return matchedAttributes != null; } @@ -198,4 +196,4 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers return string.Equals(name, attribute.Name, StringComparison.OrdinalIgnoreCase); } } -} \ No newline at end of file +} diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Razor.TagHelpers/ReadOnlyTagHelperAttributeList.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Razor.TagHelpers/ReadOnlyTagHelperAttributeList.cs index f3d1569a59..b866dff7db 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Razor.TagHelpers/ReadOnlyTagHelperAttributeList.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.MvcShim/Microsoft.AspNetCore.Razor.TagHelpers/ReadOnlyTagHelperAttributeList.cs @@ -12,8 +12,6 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers /// public abstract class ReadOnlyTagHelperAttributeList : ReadOnlyCollection { - private static readonly IReadOnlyList EmptyList = new TagHelperAttribute[0]; - /// /// Instantiates a new instance of with an empty /// collection. @@ -138,7 +136,7 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers matchedAttributes.Add(Items[i]); } } - attributes = matchedAttributes ?? EmptyList; + attributes = matchedAttributes ?? Array.Empty() as IReadOnlyList; return matchedAttributes != null; } diff --git a/src/Security/Authentication/Certificate/src/CertificateAuthenticationHandler.cs b/src/Security/Authentication/Certificate/src/CertificateAuthenticationHandler.cs index caf77f982a..91a6cc49ba 100644 --- a/src/Security/Authentication/Certificate/src/CertificateAuthenticationHandler.cs +++ b/src/Security/Authentication/Certificate/src/CertificateAuthenticationHandler.cs @@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate var certificateIsValid = chain.Build(clientCertificate); if (!certificateIsValid) { - var chainErrors = new List(); + var chainErrors = new List(chain.ChainStatus.Length); foreach (var validationFailure in chain.ChainStatus) { chainErrors.Add($"{validationFailure.Status} {validationFailure.StatusInformation}"); diff --git a/src/Security/Authentication/JwtBearer/src/JwtBearerHandler.cs b/src/Security/Authentication/JwtBearer/src/JwtBearerHandler.cs index a190613d9d..f3c851e929 100644 --- a/src/Security/Authentication/JwtBearer/src/JwtBearerHandler.cs +++ b/src/Security/Authentication/JwtBearer/src/JwtBearerHandler.cs @@ -274,7 +274,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer private static string CreateErrorDescription(Exception authFailure) { - IEnumerable exceptions; + IReadOnlyCollection exceptions; if (authFailure is AggregateException agEx) { exceptions = agEx.InnerExceptions; @@ -284,7 +284,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer exceptions = new[] { authFailure }; } - var messages = new List(); + var messages = new List(exceptions.Count); foreach (var ex in exceptions) { diff --git a/src/Servers/HttpSys/src/AuthenticationManager.cs b/src/Servers/HttpSys/src/AuthenticationManager.cs index f8ffc49af1..a15ff2192f 100644 --- a/src/Servers/HttpSys/src/AuthenticationManager.cs +++ b/src/Servers/HttpSys/src/AuthenticationManager.cs @@ -107,13 +107,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys internal static IList GenerateChallenges(AuthenticationSchemes authSchemes) { - IList challenges = new List(); - if (authSchemes == AuthenticationSchemes.None) { - return challenges; + return Array.Empty(); } + IList challenges = new List(); + // Order by strength. if ((authSchemes & AuthenticationSchemes.Kerberos) == AuthenticationSchemes.Kerberos) { diff --git a/src/Servers/HttpSys/src/HttpSysListener.cs b/src/Servers/HttpSys/src/HttpSysListener.cs index 89ab345389..4f4694ff5c 100644 --- a/src/Servers/HttpSys/src/HttpSysListener.cs +++ b/src/Servers/HttpSys/src/HttpSysListener.cs @@ -343,7 +343,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys // Copied from the multi-value headers section of SerializeHeaders if (authChallenges != null && authChallenges.Count > 0) { - pinnedHeaders = new List(); + pinnedHeaders = new List(authChallenges.Count + 3); HttpApiTypes.HTTP_RESPONSE_INFO[] knownHeaderInfo = null; knownHeaderInfo = new HttpApiTypes.HTTP_RESPONSE_INFO[1]; diff --git a/src/Shared/Buffers.Testing/ReadOnlySequenceFactory.cs b/src/Shared/Buffers.Testing/ReadOnlySequenceFactory.cs index 9ffeab03b9..0a4faef2da 100644 --- a/src/Shared/Buffers.Testing/ReadOnlySequenceFactory.cs +++ b/src/Shared/Buffers.Testing/ReadOnlySequenceFactory.cs @@ -92,7 +92,7 @@ namespace System.Buffers public override ReadOnlySequence CreateWithContent(byte[] data) { - var segments = new List(); + var segments = new List((data.Length * 2) + 1); segments.Add(Array.Empty()); foreach (var b in data) diff --git a/src/Shared/ObjectMethodExecutor/ObjectMethodExecutor.cs b/src/Shared/ObjectMethodExecutor/ObjectMethodExecutor.cs index 084f7f0aad..a3abd893dc 100644 --- a/src/Shared/ObjectMethodExecutor/ObjectMethodExecutor.cs +++ b/src/Shared/ObjectMethodExecutor/ObjectMethodExecutor.cs @@ -157,8 +157,8 @@ namespace Microsoft.Extensions.Internal var parametersParameter = Expression.Parameter(typeof(object[]), "parameters"); // Build parameter list - var parameters = new List(); var paramInfos = methodInfo.GetParameters(); + var parameters = new List(paramInfos.Length); for (int i = 0; i < paramInfos.Length; i++) { var paramInfo = paramInfos[i]; @@ -209,8 +209,8 @@ namespace Microsoft.Extensions.Internal var parametersParameter = Expression.Parameter(typeof(object[]), "parameters"); // Build parameter list - var parameters = new List(); var paramInfos = methodInfo.GetParameters(); + var parameters = new List(paramInfos.Length); for (int i = 0; i < paramInfos.Length; i++) { var paramInfo = paramInfos[i]; diff --git a/src/Shared/StackTrace/StackFrame/StackTraceHelper.cs b/src/Shared/StackTrace/StackFrame/StackTraceHelper.cs index 5c38980109..3f8249a576 100644 --- a/src/Shared/StackTrace/StackFrame/StackTraceHelper.cs +++ b/src/Shared/StackTrace/StackFrame/StackTraceHelper.cs @@ -18,12 +18,10 @@ namespace Microsoft.Extensions.StackTrace.Sources { public static IList GetFrames(Exception exception, out AggregateException? error) { - var frames = new List(); - if (exception == null) { error = default; - return frames; + return Array.Empty(); } var needFileInfo = true; @@ -33,9 +31,11 @@ namespace Microsoft.Extensions.StackTrace.Sources if (stackFrames == null) { error = default; - return frames; + return Array.Empty(); } + var frames = new List(stackFrames.Length); + List? exceptions = null; for (var i = 0; i < stackFrames.Length; i++) diff --git a/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs b/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs index 84f62abdc0..de7feb973a 100644 --- a/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs +++ b/src/SignalR/common/Http.Connections/src/Internal/HttpConnectionManager.cs @@ -180,7 +180,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal // Stop firing the timer _nextHeartbeat.Stop(); - var tasks = new List(); + var tasks = new List(_connections.Count); // REVIEW: In the future we can consider a hybrid where we first try to wait for shutdown // for a certain time frame then after some grace period we shutdown more aggressively diff --git a/src/SignalR/server/Core/src/HubConnectionHandler.cs b/src/SignalR/server/Core/src/HubConnectionHandler.cs index c5970a96a6..40745494ad 100644 --- a/src/SignalR/server/Core/src/HubConnectionHandler.cs +++ b/src/SignalR/server/Core/src/HubConnectionHandler.cs @@ -73,8 +73,7 @@ namespace Microsoft.AspNetCore.SignalR if (_hubOptions.HubFilters != null) { - hubFilters = new List(); - hubFilters.AddRange(_hubOptions.HubFilters); + hubFilters = new List(_hubOptions.HubFilters); } } else @@ -84,8 +83,7 @@ namespace Microsoft.AspNetCore.SignalR if (_globalHubOptions.HubFilters != null) { - hubFilters = new List(); - hubFilters.AddRange(_globalHubOptions.HubFilters); + hubFilters = new List(_globalHubOptions.HubFilters); } } diff --git a/src/SignalR/server/Core/src/HubOptionsSetup.cs b/src/SignalR/server/Core/src/HubOptionsSetup.cs index 6b6a08abab..c41fd8fb49 100644 --- a/src/SignalR/server/Core/src/HubOptionsSetup.cs +++ b/src/SignalR/server/Core/src/HubOptionsSetup.cs @@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.SignalR if (options.SupportedProtocols == null) { - options.SupportedProtocols = new List(); + options.SupportedProtocols = new List(_defaultProtocols.Count); } if (options.StreamBufferCapacity == null) diff --git a/src/SignalR/server/StackExchangeRedis/src/Internal/DefaultHubMessageSerializer.cs b/src/SignalR/server/StackExchangeRedis/src/Internal/DefaultHubMessageSerializer.cs index 7bcd4089e8..13bcc6f490 100644 --- a/src/SignalR/server/StackExchangeRedis/src/Internal/DefaultHubMessageSerializer.cs +++ b/src/SignalR/server/StackExchangeRedis/src/Internal/DefaultHubMessageSerializer.cs @@ -10,11 +10,12 @@ namespace Microsoft.AspNetCore.SignalR.Internal { internal class DefaultHubMessageSerializer { - private readonly List _hubProtocols = new List(); + private readonly List _hubProtocols; public DefaultHubMessageSerializer(IHubProtocolResolver hubProtocolResolver, IList globalSupportedProtocols, IList hubSupportedProtocols) { var supportedProtocols = hubSupportedProtocols ?? globalSupportedProtocols ?? Array.Empty(); + _hubProtocols = new List(supportedProtocols.Count); foreach (var protocolName in supportedProtocols) { var protocol = hubProtocolResolver.GetProtocol(protocolName, (supportedProtocols as IReadOnlyList) ?? supportedProtocols.ToList()); diff --git a/src/SignalR/server/StackExchangeRedis/src/RedisHubLifetimeManager.cs b/src/SignalR/server/StackExchangeRedis/src/RedisHubLifetimeManager.cs index df81ed61b3..b2e5b1f8fb 100644 --- a/src/SignalR/server/StackExchangeRedis/src/RedisHubLifetimeManager.cs +++ b/src/SignalR/server/StackExchangeRedis/src/RedisHubLifetimeManager.cs @@ -465,7 +465,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis { var invocation = _protocol.ReadInvocation((byte[])channelMessage.Message); - var tasks = new List(); + var tasks = new List(subscriptions.Count); foreach (var userConnection in subscriptions) { tasks.Add(userConnection.WriteAsync(invocation.Message).AsTask()); @@ -491,7 +491,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis { var invocation = _protocol.ReadInvocation((byte[])channelMessage.Message); - var tasks = new List(); + var tasks = new List(groupConnections.Count); foreach (var groupConnection in groupConnections) { if (invocation.ExcludedConnectionIds?.Contains(groupConnection.ConnectionId) == true)