Right-size Lists when created (#23714)

Create new instances of List<T> with an appropriate capacity for the items that will be added.
Use Array.Empty<T>() where appropriate, rather than create an empty list and then return it.
This commit is contained in:
Martin Costello 2020-08-19 17:45:52 +01:00 committed by GitHub
parent d2f34d6d99
commit b22512de0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 71 additions and 66 deletions

View File

@ -98,7 +98,7 @@ namespace Microsoft.Extensions.FileProviders.Embedded.Manifest
private ManifestEntry[] CopyChildren() private ManifestEntry[] CopyChildren()
{ {
var list = new List<ManifestEntry>(); var list = new List<ManifestEntry>(Children.Count);
for (int i = 0; i < Children.Count; i++) for (int i = 0; i < Children.Count; i++)
{ {
var child = Children[i]; var child = Children[i];

View File

@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Http.Features
} }
else else
{ {
var headers = new List<string>(); var headers = new List<string>(_parsedValues.Count);
foreach (var pair in _parsedValues) foreach (var pair in _parsedValues)
{ {
headers.Add(new CookieHeaderValue(pair.Key, pair.Value).ToString()); headers.Add(new CookieHeaderValue(pair.Key, pair.Value).ToString());

View File

@ -497,7 +497,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
updatedParameterPolicies = new Dictionary<string, List<RoutePatternParameterPolicyReference>>(StringComparer.OrdinalIgnoreCase); updatedParameterPolicies = new Dictionary<string, List<RoutePatternParameterPolicyReference>>(StringComparer.OrdinalIgnoreCase);
} }
parameterConstraints = new List<RoutePatternParameterPolicyReference>(); parameterConstraints = new List<RoutePatternParameterPolicyReference>(parameter.ParameterPolicies.Count);
updatedParameterPolicies.Add(parameter.Name, parameterConstraints); updatedParameterPolicies.Add(parameter.Name, parameterConstraints);
} }

View File

@ -169,16 +169,22 @@ namespace Microsoft.AspNetCore.Identity
public virtual async Task RefreshSignInAsync(TUser user) public virtual async Task RefreshSignInAsync(TUser user)
{ {
var auth = await Context.AuthenticateAsync(IdentityConstants.ApplicationScheme); var auth = await Context.AuthenticateAsync(IdentityConstants.ApplicationScheme);
var claims = new List<Claim>(); IList<Claim> claims = Array.Empty<Claim>();
var authenticationMethod = auth?.Principal?.FindFirst(ClaimTypes.AuthenticationMethod); var authenticationMethod = auth?.Principal?.FindFirst(ClaimTypes.AuthenticationMethod);
if (authenticationMethod != null)
{
claims.Add(authenticationMethod);
}
var amr = auth?.Principal?.FindFirst("amr"); var amr = auth?.Principal?.FindFirst("amr");
if (amr != null)
if (authenticationMethod != null || amr != null)
{ {
claims.Add(amr); claims = new List<Claim>();
if (authenticationMethod != null)
{
claims.Add(authenticationMethod);
}
if (amr != null)
{
claims.Add(amr);
}
} }
await SignInWithClaimsAsync(user, auth?.Properties, claims); await SignInWithClaimsAsync(user, auth?.Properties, claims);
@ -203,9 +209,10 @@ namespace Microsoft.AspNetCore.Identity
/// <returns>The task object representing the asynchronous operation.</returns> /// <returns>The task object representing the asynchronous operation.</returns>
public virtual Task SignInAsync(TUser user, AuthenticationProperties authenticationProperties, string authenticationMethod = null) public virtual Task SignInAsync(TUser user, AuthenticationProperties authenticationProperties, string authenticationMethod = null)
{ {
var additionalClaims = new List<Claim>(); IList<Claim> additionalClaims = Array.Empty<Claim>();
if (authenticationMethod != null) if (authenticationMethod != null)
{ {
additionalClaims = new List<Claim>();
additionalClaims.Add(new Claim(ClaimTypes.AuthenticationMethod, authenticationMethod)); additionalClaims.Add(new Claim(ClaimTypes.AuthenticationMethod, authenticationMethod));
} }
return SignInWithClaimsAsync(user, authenticationProperties, additionalClaims); return SignInWithClaimsAsync(user, authenticationProperties, additionalClaims);

View File

@ -122,7 +122,7 @@ namespace Microsoft.AspNetCore.Builder
/// <returns>The <see cref="RequestLocalizationOptions"/>.</returns> /// <returns>The <see cref="RequestLocalizationOptions"/>.</returns>
public RequestLocalizationOptions AddSupportedCultures(params string[] cultures) public RequestLocalizationOptions AddSupportedCultures(params string[] cultures)
{ {
var supportedCultures = new List<CultureInfo>(); var supportedCultures = new List<CultureInfo>(cultures.Length);
foreach (var culture in cultures) foreach (var culture in cultures)
{ {
@ -140,7 +140,7 @@ namespace Microsoft.AspNetCore.Builder
/// <returns>The <see cref="RequestLocalizationOptions"/>.</returns> /// <returns>The <see cref="RequestLocalizationOptions"/>.</returns>
public RequestLocalizationOptions AddSupportedUICultures(params string[] uiCultures) public RequestLocalizationOptions AddSupportedUICultures(params string[] uiCultures)
{ {
var supportedUICultures = new List<CultureInfo>(); var supportedUICultures = new List<CultureInfo>(uiCultures.Length);
foreach (var culture in uiCultures) foreach (var culture in uiCultures)
{ {
supportedUICultures.Add(new CultureInfo(culture)); supportedUICultures.Add(new CultureInfo(culture));

View File

@ -309,7 +309,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
// Text to show as the attribute route template for conventionally routed actions. // Text to show as the attribute route template for conventionally routed actions.
var nullTemplate = Resources.AttributeRoute_NullTemplateRepresentation; var nullTemplate = Resources.AttributeRoute_NullTemplateRepresentation;
var actionDescriptions = new List<string>(); var actionDescriptions = new List<string>(actions.Count);
for (var i = 0; i < actions.Count; i++) for (var i = 0; i < actions.Count; i++)
{ {
var (action, selector) = actions[i]; var (action, selector) = actions[i];

View File

@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
private static void AddParameterDescriptors(ActionDescriptor actionDescriptor, ActionModel action) private static void AddParameterDescriptors(ActionDescriptor actionDescriptor, ActionModel action)
{ {
var parameterDescriptors = new List<ParameterDescriptor>(); var parameterDescriptors = new List<ParameterDescriptor>(action.Parameters.Count);
foreach (var parameter in action.Parameters) foreach (var parameter in action.Parameters)
{ {
var parameterDescriptor = CreateParameterDescriptor(parameter); var parameterDescriptor = CreateParameterDescriptor(parameter);

View File

@ -352,7 +352,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
// This is fairly complicated so that we maintain referential equality between items in // This is fairly complicated so that we maintain referential equality between items in
// ActionModel.Attributes and ActionModel.Attributes[*].Attribute. // ActionModel.Attributes and ActionModel.Attributes[*].Attribute.
var applicableAttributes = new List<object>(); var applicableAttributes = new List<object>(routeAttributes.Length);
foreach (var attribute in attributes) foreach (var attribute in attributes)
{ {
if (attribute is IRouteTemplateProvider) if (attribute is IRouteTemplateProvider)

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Mvc
/// <param name="include">Names of parameters to include in binding.</param> /// <param name="include">Names of parameters to include in binding.</param>
public BindAttribute(params string[] include) public BindAttribute(params string[] include)
{ {
var items = new List<string>(); var items = new List<string>(include.Length);
foreach (var item in include) foreach (var item in include)
{ {
items.AddRange(SplitString(item)); items.AddRange(SplitString(item));

View File

@ -199,7 +199,7 @@ namespace Microsoft.AspNetCore.Mvc
private MediaTypeCollection GetContentTypes(string firstArg, string[] args) private MediaTypeCollection GetContentTypes(string firstArg, string[] args)
{ {
var completeArgs = new List<string>(); var completeArgs = new List<string>(args.Length + 1);
completeArgs.Add(firstArg); completeArgs.Add(firstArg);
completeArgs.AddRange(args); completeArgs.AddRange(args);
var contentTypes = new MediaTypeCollection(); var contentTypes = new MediaTypeCollection();

View File

@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
{ {
if (mediaTypes == null) if (mediaTypes == null)
{ {
mediaTypes = new List<string>(); mediaTypes = new List<string>(SupportedMediaTypes.Count);
} }
mediaTypes.Add(mediaType); mediaTypes.Add(mediaType);

View File

@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
{ {
if (mediaTypes == null) if (mediaTypes == null)
{ {
mediaTypes = new List<string>(); mediaTypes = new List<string>(SupportedMediaTypes.Count);
} }
mediaTypes.Add(contentType); mediaTypes.Add(contentType);
@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
{ {
if (mediaTypes == null) if (mediaTypes == null)
{ {
mediaTypes = new List<string>(); mediaTypes = new List<string>(SupportedMediaTypes.Count);
} }
mediaTypes.Add(mediaType); mediaTypes.Add(mediaType);

View File

@ -135,10 +135,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
RouteContext context, RouteContext context,
IReadOnlyList<ActionDescriptor> actions) IReadOnlyList<ActionDescriptor> actions)
{ {
var candidates = new List<ActionSelectorCandidate>(); var actionsCount = actions.Count;
var candidates = new List<ActionSelectorCandidate>(actionsCount);
// Perf: Avoid allocations // Perf: Avoid allocations
for (var i = 0; i < actions.Count; i++) for (var i = 0; i < actionsCount; i++)
{ {
var action = actions[i]; var action = actions[i];
var constraints = _actionConstraintCache.GetActionConstraints(context.HttpContext, action); var constraints = _actionConstraintCache.GetActionConstraints(context.HttpContext, action);
@ -150,9 +151,10 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
List<ActionDescriptor> results = null; List<ActionDescriptor> results = null;
if (matches != null) if (matches != null)
{ {
results = new List<ActionDescriptor>(matches.Count); var matchesCount = matches.Count;
results = new List<ActionDescriptor>(matchesCount);
// Perf: Avoid allocations // Perf: Avoid allocations
for (var i = 0; i < matches.Count; i++) for (var i = 0; i < matchesCount; i++)
{ {
var candidate = matches[i]; var candidate = matches[i];
results.Add(candidate.Action); results.Add(candidate.Action);

View File

@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Mvc
private MediaTypeCollection GetContentTypes(string firstArg, string[] args) private MediaTypeCollection GetContentTypes(string firstArg, string[] args)
{ {
var completeArgs = new List<string>(); var completeArgs = new List<string>(args.Length + 1);
completeArgs.Add(firstArg); completeArgs.Add(firstArg);
completeArgs.AddRange(args); completeArgs.AddRange(args);
var contentTypes = new MediaTypeCollection(); var contentTypes = new MediaTypeCollection();

View File

@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation
// For unit testing // For unit testing
internal IEnumerable<string> GetReferencePaths() internal IEnumerable<string> GetReferencePaths()
{ {
var referencePaths = new List<string>(); var referencePaths = new List<string>(_options.AdditionalReferencePaths.Count);
foreach (var part in _partManager.ApplicationParts) foreach (var part in _partManager.ApplicationParts)
{ {

View File

@ -83,7 +83,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure
private static object DeserializeArray(in JsonElement arrayElement) 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. // 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 // 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) if (arrayElement[0].ValueKind == JsonValueKind.String)
{ {
var array = new List<string>(); var array = new List<string>(arrayLength);
foreach (var item in arrayElement.EnumerateArray()) foreach (var item in arrayElement.EnumerateArray())
{ {
@ -104,7 +105,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure
} }
else if (arrayElement[0].ValueKind == JsonValueKind.Number) else if (arrayElement[0].ValueKind == JsonValueKind.Number)
{ {
var array = new List<int>(); var array = new List<int>(arrayLength);
foreach (var item in arrayElement.EnumerateArray()) foreach (var item in arrayElement.EnumerateArray())
{ {

View File

@ -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 // 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. // correct context for intellisense when typing in the attribute.
var eventArgsType = node.TagHelper.GetEventArgsType(); var eventArgsType = node.TagHelper.GetEventArgsType();
var tokens = new List<IntermediateToken>() var tokens = new List<IntermediateToken>(original.Count + 2)
{ {
new IntermediateToken() new IntermediateToken()
{ {

View File

@ -96,7 +96,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
private static string[] ExpandResponseFiles(string[] args) private static string[] ExpandResponseFiles(string[] args)
{ {
var expandedArgs = new List<string>(); var expandedArgs = new List<string>(args.Length);
foreach (var arg in args) foreach (var arg in args)
{ {
if (!arg.StartsWith("@", StringComparison.Ordinal)) if (!arg.StartsWith("@", StringComparison.Ordinal))

View File

@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
/// </summary> /// </summary>
private void WaitForAnyCompletion(CancellationToken cancellationToken) private void WaitForAnyCompletion(CancellationToken cancellationToken)
{ {
var all = new List<Task>(); var all = new List<Task>(_connections.Count + 3);
all.AddRange(_connections); all.AddRange(_connections);
all.Add(_timeoutTask); all.Add(_timeoutTask);
all.Add(_listenTask); all.Add(_listenTask);

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Razor.Tools
internal static AssemblyIdentity[] GetReferencedAssembliesOrThrow(this MetadataReader reader) internal static AssemblyIdentity[] GetReferencedAssembliesOrThrow(this MetadataReader reader)
{ {
var references = new List<AssemblyIdentity>(); var references = new List<AssemblyIdentity>(reader.AssemblyReferences.Count);
foreach (var referenceHandle in reader.AssemblyReferences) foreach (var referenceHandle in reader.AssemblyReferences)
{ {

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Tasks
public override bool Execute() public override bool Execute()
{ {
var referenceItems = new List<AssemblyItem>(); var referenceItems = new List<AssemblyItem>(Assemblies.Length);
foreach (var item in Assemblies) foreach (var item in Assemblies)
{ {
const string FusionNameKey = "FusionName"; const string FusionNameKey = "FusionName";

View File

@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Razor.Tasks
var metadataReader = peReader.GetMetadataReader(); var metadataReader = peReader.GetMetadataReader();
var references = new List<AssemblyItem>(); var references = new List<AssemblyItem>(metadataReader.AssemblyReferences.Count);
foreach (var handle in metadataReader.AssemblyReferences) foreach (var handle in metadataReader.AssemblyReferences)
{ {
var reference = metadataReader.GetAssemblyReference(handle); var reference = metadataReader.GetAssemblyReference(handle);

View File

@ -12,8 +12,6 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers
/// </summary> /// </summary>
public abstract class ReadOnlyTagHelperAttributeList : ReadOnlyCollection<TagHelperAttribute> public abstract class ReadOnlyTagHelperAttributeList : ReadOnlyCollection<TagHelperAttribute>
{ {
private static readonly IReadOnlyList<TagHelperAttribute> EmptyList = new TagHelperAttribute[0];
/// <summary> /// <summary>
/// Instantiates a new instance of <see cref="ReadOnlyTagHelperAttributeList"/> with an empty /// Instantiates a new instance of <see cref="ReadOnlyTagHelperAttributeList"/> with an empty
/// collection. /// collection.
@ -146,7 +144,7 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers
matchedAttributes.Add(attribute); matchedAttributes.Add(attribute);
} }
} }
attributes = matchedAttributes ?? EmptyList; attributes = matchedAttributes ?? (IReadOnlyList<TagHelperAttribute>)Array.Empty<TagHelperAttribute>();
return matchedAttributes != null; return matchedAttributes != null;
} }
@ -198,4 +196,4 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers
return string.Equals(name, attribute.Name, StringComparison.OrdinalIgnoreCase); return string.Equals(name, attribute.Name, StringComparison.OrdinalIgnoreCase);
} }
} }
} }

View File

@ -12,8 +12,6 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers
/// </summary> /// </summary>
public abstract class ReadOnlyTagHelperAttributeList : ReadOnlyCollection<TagHelperAttribute> public abstract class ReadOnlyTagHelperAttributeList : ReadOnlyCollection<TagHelperAttribute>
{ {
private static readonly IReadOnlyList<TagHelperAttribute> EmptyList = new TagHelperAttribute[0];
/// <summary> /// <summary>
/// Instantiates a new instance of <see cref="ReadOnlyTagHelperAttributeList"/> with an empty /// Instantiates a new instance of <see cref="ReadOnlyTagHelperAttributeList"/> with an empty
/// collection. /// collection.
@ -138,7 +136,7 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers
matchedAttributes.Add(Items[i]); matchedAttributes.Add(Items[i]);
} }
} }
attributes = matchedAttributes ?? EmptyList; attributes = matchedAttributes ?? Array.Empty<TagHelperAttribute>() as IReadOnlyList<TagHelperAttribute>;
return matchedAttributes != null; return matchedAttributes != null;
} }

View File

@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate
var certificateIsValid = chain.Build(clientCertificate); var certificateIsValid = chain.Build(clientCertificate);
if (!certificateIsValid) if (!certificateIsValid)
{ {
var chainErrors = new List<string>(); var chainErrors = new List<string>(chain.ChainStatus.Length);
foreach (var validationFailure in chain.ChainStatus) foreach (var validationFailure in chain.ChainStatus)
{ {
chainErrors.Add($"{validationFailure.Status} {validationFailure.StatusInformation}"); chainErrors.Add($"{validationFailure.Status} {validationFailure.StatusInformation}");

View File

@ -274,7 +274,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
private static string CreateErrorDescription(Exception authFailure) private static string CreateErrorDescription(Exception authFailure)
{ {
IEnumerable<Exception> exceptions; IReadOnlyCollection<Exception> exceptions;
if (authFailure is AggregateException agEx) if (authFailure is AggregateException agEx)
{ {
exceptions = agEx.InnerExceptions; exceptions = agEx.InnerExceptions;
@ -284,7 +284,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer
exceptions = new[] { authFailure }; exceptions = new[] { authFailure };
} }
var messages = new List<string>(); var messages = new List<string>(exceptions.Count);
foreach (var ex in exceptions) foreach (var ex in exceptions)
{ {

View File

@ -107,13 +107,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal static IList<string> GenerateChallenges(AuthenticationSchemes authSchemes) internal static IList<string> GenerateChallenges(AuthenticationSchemes authSchemes)
{ {
IList<string> challenges = new List<string>();
if (authSchemes == AuthenticationSchemes.None) if (authSchemes == AuthenticationSchemes.None)
{ {
return challenges; return Array.Empty<string>();
} }
IList<string> challenges = new List<string>();
// Order by strength. // Order by strength.
if ((authSchemes & AuthenticationSchemes.Kerberos) == AuthenticationSchemes.Kerberos) if ((authSchemes & AuthenticationSchemes.Kerberos) == AuthenticationSchemes.Kerberos)
{ {

View File

@ -343,7 +343,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// Copied from the multi-value headers section of SerializeHeaders // Copied from the multi-value headers section of SerializeHeaders
if (authChallenges != null && authChallenges.Count > 0) if (authChallenges != null && authChallenges.Count > 0)
{ {
pinnedHeaders = new List<GCHandle>(); pinnedHeaders = new List<GCHandle>(authChallenges.Count + 3);
HttpApiTypes.HTTP_RESPONSE_INFO[] knownHeaderInfo = null; HttpApiTypes.HTTP_RESPONSE_INFO[] knownHeaderInfo = null;
knownHeaderInfo = new HttpApiTypes.HTTP_RESPONSE_INFO[1]; knownHeaderInfo = new HttpApiTypes.HTTP_RESPONSE_INFO[1];

View File

@ -92,7 +92,7 @@ namespace System.Buffers
public override ReadOnlySequence<byte> CreateWithContent(byte[] data) public override ReadOnlySequence<byte> CreateWithContent(byte[] data)
{ {
var segments = new List<byte[]>(); var segments = new List<byte[]>((data.Length * 2) + 1);
segments.Add(Array.Empty<byte>()); segments.Add(Array.Empty<byte>());
foreach (var b in data) foreach (var b in data)

View File

@ -157,8 +157,8 @@ namespace Microsoft.Extensions.Internal
var parametersParameter = Expression.Parameter(typeof(object[]), "parameters"); var parametersParameter = Expression.Parameter(typeof(object[]), "parameters");
// Build parameter list // Build parameter list
var parameters = new List<Expression>();
var paramInfos = methodInfo.GetParameters(); var paramInfos = methodInfo.GetParameters();
var parameters = new List<Expression>(paramInfos.Length);
for (int i = 0; i < paramInfos.Length; i++) for (int i = 0; i < paramInfos.Length; i++)
{ {
var paramInfo = paramInfos[i]; var paramInfo = paramInfos[i];
@ -209,8 +209,8 @@ namespace Microsoft.Extensions.Internal
var parametersParameter = Expression.Parameter(typeof(object[]), "parameters"); var parametersParameter = Expression.Parameter(typeof(object[]), "parameters");
// Build parameter list // Build parameter list
var parameters = new List<Expression>();
var paramInfos = methodInfo.GetParameters(); var paramInfos = methodInfo.GetParameters();
var parameters = new List<Expression>(paramInfos.Length);
for (int i = 0; i < paramInfos.Length; i++) for (int i = 0; i < paramInfos.Length; i++)
{ {
var paramInfo = paramInfos[i]; var paramInfo = paramInfos[i];

View File

@ -18,12 +18,10 @@ namespace Microsoft.Extensions.StackTrace.Sources
{ {
public static IList<StackFrameInfo> GetFrames(Exception exception, out AggregateException? error) public static IList<StackFrameInfo> GetFrames(Exception exception, out AggregateException? error)
{ {
var frames = new List<StackFrameInfo>();
if (exception == null) if (exception == null)
{ {
error = default; error = default;
return frames; return Array.Empty<StackFrameInfo>();
} }
var needFileInfo = true; var needFileInfo = true;
@ -33,9 +31,11 @@ namespace Microsoft.Extensions.StackTrace.Sources
if (stackFrames == null) if (stackFrames == null)
{ {
error = default; error = default;
return frames; return Array.Empty<StackFrameInfo>();
} }
var frames = new List<StackFrameInfo>(stackFrames.Length);
List<Exception>? exceptions = null; List<Exception>? exceptions = null;
for (var i = 0; i < stackFrames.Length; i++) for (var i = 0; i < stackFrames.Length; i++)

View File

@ -180,7 +180,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal
// Stop firing the timer // Stop firing the timer
_nextHeartbeat.Stop(); _nextHeartbeat.Stop();
var tasks = new List<Task>(); var tasks = new List<Task>(_connections.Count);
// REVIEW: In the future we can consider a hybrid where we first try to wait for shutdown // 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 // for a certain time frame then after some grace period we shutdown more aggressively

View File

@ -73,8 +73,7 @@ namespace Microsoft.AspNetCore.SignalR
if (_hubOptions.HubFilters != null) if (_hubOptions.HubFilters != null)
{ {
hubFilters = new List<IHubFilter>(); hubFilters = new List<IHubFilter>(_hubOptions.HubFilters);
hubFilters.AddRange(_hubOptions.HubFilters);
} }
} }
else else
@ -84,8 +83,7 @@ namespace Microsoft.AspNetCore.SignalR
if (_globalHubOptions.HubFilters != null) if (_globalHubOptions.HubFilters != null)
{ {
hubFilters = new List<IHubFilter>(); hubFilters = new List<IHubFilter>(_globalHubOptions.HubFilters);
hubFilters.AddRange(_globalHubOptions.HubFilters);
} }
} }

View File

@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.SignalR
if (options.SupportedProtocols == null) if (options.SupportedProtocols == null)
{ {
options.SupportedProtocols = new List<string>(); options.SupportedProtocols = new List<string>(_defaultProtocols.Count);
} }
if (options.StreamBufferCapacity == null) if (options.StreamBufferCapacity == null)

View File

@ -10,11 +10,12 @@ namespace Microsoft.AspNetCore.SignalR.Internal
{ {
internal class DefaultHubMessageSerializer internal class DefaultHubMessageSerializer
{ {
private readonly List<IHubProtocol> _hubProtocols = new List<IHubProtocol>(); private readonly List<IHubProtocol> _hubProtocols;
public DefaultHubMessageSerializer(IHubProtocolResolver hubProtocolResolver, IList<string> globalSupportedProtocols, IList<string> hubSupportedProtocols) public DefaultHubMessageSerializer(IHubProtocolResolver hubProtocolResolver, IList<string> globalSupportedProtocols, IList<string> hubSupportedProtocols)
{ {
var supportedProtocols = hubSupportedProtocols ?? globalSupportedProtocols ?? Array.Empty<string>(); var supportedProtocols = hubSupportedProtocols ?? globalSupportedProtocols ?? Array.Empty<string>();
_hubProtocols = new List<IHubProtocol>(supportedProtocols.Count);
foreach (var protocolName in supportedProtocols) foreach (var protocolName in supportedProtocols)
{ {
var protocol = hubProtocolResolver.GetProtocol(protocolName, (supportedProtocols as IReadOnlyList<string>) ?? supportedProtocols.ToList()); var protocol = hubProtocolResolver.GetProtocol(protocolName, (supportedProtocols as IReadOnlyList<string>) ?? supportedProtocols.ToList());

View File

@ -465,7 +465,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis
{ {
var invocation = _protocol.ReadInvocation((byte[])channelMessage.Message); var invocation = _protocol.ReadInvocation((byte[])channelMessage.Message);
var tasks = new List<Task>(); var tasks = new List<Task>(subscriptions.Count);
foreach (var userConnection in subscriptions) foreach (var userConnection in subscriptions)
{ {
tasks.Add(userConnection.WriteAsync(invocation.Message).AsTask()); tasks.Add(userConnection.WriteAsync(invocation.Message).AsTask());
@ -491,7 +491,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis
{ {
var invocation = _protocol.ReadInvocation((byte[])channelMessage.Message); var invocation = _protocol.ReadInvocation((byte[])channelMessage.Message);
var tasks = new List<Task>(); var tasks = new List<Task>(groupConnections.Count);
foreach (var groupConnection in groupConnections) foreach (var groupConnection in groupConnections)
{ {
if (invocation.ExcludedConnectionIds?.Contains(groupConnection.ConnectionId) == true) if (invocation.ExcludedConnectionIds?.Contains(groupConnection.ConnectionId) == true)