Skip to content

Commit c660e9b

Browse files
authored
Add a FeaturesCollection constructor that supports initial capacity (#31381)
* Add a FeaturesCollection constructor that supports initial capacity
1 parent 2c4444f commit c660e9b

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

src/Http/Http.Features/src/FeatureCollection.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class FeatureCollection : IFeatureCollection
1515
{
1616
private static readonly KeyComparer FeatureKeyComparer = new KeyComparer();
1717
private readonly IFeatureCollection? _defaults;
18+
private readonly int _initialCapacity;
1819
private IDictionary<Type, object>? _features;
1920
private volatile int _containerRevision;
2021

@@ -25,6 +26,21 @@ public FeatureCollection()
2526
{
2627
}
2728

29+
/// <summary>
30+
/// Initializes a new instance of <see cref="FeatureCollection"/> with the specified initial capacity.
31+
/// </summary>
32+
/// <param name="initialCapacity">The initial number of elements that the collection can contain.</param>
33+
/// <exception cref="System.ArgumentOutOfRangeException"><paramref name="initialCapacity"/> is less than 0</exception>
34+
public FeatureCollection(int initialCapacity)
35+
{
36+
if (initialCapacity < 0)
37+
{
38+
throw new ArgumentOutOfRangeException(nameof(initialCapacity));
39+
}
40+
41+
_initialCapacity = initialCapacity;
42+
}
43+
2844
/// <summary>
2945
/// Initializes a new instance of <see cref="FeatureCollection"/> with the specified defaults.
3046
/// </summary>
@@ -73,7 +89,7 @@ public object? this[Type key]
7389

7490
if (_features == null)
7591
{
76-
_features = new Dictionary<Type, object>();
92+
_features = new Dictionary<Type, object>(_initialCapacity);
7793
}
7894
_features[key] = value;
7995
_containerRevision++;

src/Http/Http.Features/src/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ Microsoft.AspNetCore.Http.Features.FeatureCollection.Set<TFeature>(TFeature? ins
1313
Microsoft.AspNetCore.Http.Features.IFeatureCollection.Get<TFeature>() -> TFeature?
1414
Microsoft.AspNetCore.Http.Features.IFeatureCollection.Set<TFeature>(TFeature? instance) -> void
1515
Microsoft.AspNetCore.Http.Features.IServerVariablesFeature.this[string! variableName].get -> string?
16-
Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]? value) -> bool
16+
Microsoft.AspNetCore.Http.ISession.TryGetValue(string! key, out byte[]? value) -> bool
17+
Microsoft.AspNetCore.Http.Features.FeatureCollection.FeatureCollection(int initialCapacity) -> void

src/Http/Http/src/DefaultHttpContext.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ namespace Microsoft.AspNetCore.Http
1919
/// </summary>
2020
public sealed class DefaultHttpContext : HttpContext
2121
{
22+
// The initial size of the feature collection when using the default constructor; based on number of common features
23+
// https://github.com/dotnet/aspnetcore/issues/31249
24+
private const int DefaultFeatureCollectionSize = 10;
25+
2226
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
2327
private readonly static Func<IFeatureCollection, IItemsFeature> _newItemsFeature = f => new ItemsFeature();
2428
private readonly static Func<DefaultHttpContext, IServiceProvidersFeature> _newServiceProvidersFeature = context => new RequestServicesFeature(context, context.ServiceScopeFactory);
@@ -44,7 +48,7 @@ public sealed class DefaultHttpContext : HttpContext
4448
/// Initializes a new instance of the <see cref="DefaultHttpContext"/> class.
4549
/// </summary>
4650
public DefaultHttpContext()
47-
: this(new FeatureCollection())
51+
: this(new FeatureCollection(DefaultFeatureCollectionSize))
4852
{
4953
Features.Set<IHttpRequestFeature>(new HttpRequestFeature());
5054
Features.Set<IHttpResponseFeature>(new HttpResponseFeature());

0 commit comments

Comments
 (0)