Reduce allocations in Microsoft.Extensions.Configuration - #133494
Conversation
Give the provider lists an initial capacity so `List<T>` does not reallocate its backing array while it grows in the Microsoft.Extensions.Configuration APIs. Changed: - ConfigurationBuilder.Build - ConfigurationManager.ReloadSources - ReferenceCountedProviderManager.AddProvider
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @dotnet/area-extensions-configuration |
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
🟢 Approval recommended
The changes are small, localized, and preserve existing behavior while applying a standard allocation-avoidance pattern (pre-sizing lists when the final count is known).
Pull request overview
This PR reduces transient allocations in Microsoft.Extensions.Configuration by pre-sizing provider lists based on the known source count, avoiding List<T> growth reallocations in common paths.
Changes:
- Pre-allocates
List<IConfigurationProvider>capacity inConfigurationBuilder.Build()using_sources.Count. - Pre-allocates
List<IConfigurationProvider>capacity inConfigurationManager.ReloadSources()using_sources.Count. - Updates
ReferenceCountedProviderManager.AddProvider()to copy providers into a new list withCount + 1capacity before appending.
File summaries
| File | Description |
|---|---|
| src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationBuilder.cs | Pre-sizes providers list to _sources.Count before building providers. |
| src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationManager.cs | Pre-sizes the rebuilt providers list during ReloadSources() to _sources.Count. |
| src/libraries/Microsoft.Extensions.Configuration/src/ReferenceCountedProvidersManager.cs | Avoids list growth reallocation by allocating providers.Count + 1 before copying and adding a provider. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 0
- Review effort level: Lite
…CountedProvidersManager.cs Co-authored-by: Miha Zupan <mihazupan.zupan1@gmail.com>
There was a problem hiding this comment.
🟢 Approval recommended
The changes are low-risk, preserve existing behavior, and align with the intended allocation reduction by pre-sizing provider lists where the final size is already known.
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
rosebyte
left a comment
There was a problem hiding this comment.
LGTM
Thank you for the contribution!
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
Review details
Suppressed comments (1)
src/libraries/Microsoft.Extensions.Configuration/src/ReferenceCountedProvidersManager.cs:71
- The supplied benchmark shows a throughput regression for this path at the intermediate size:
Manager_AddSourcesgoes from 5,783.2 ns to 6,129.9 ns for 16 sources (ratio 1.06), even though allocations improve. Please benchmark an explicitList<IConfigurationProvider>with capacityexisting.Count + 1, followed byAddRangeandAdd, to retain the allocation win without the collection-expression lowering overhead before merging.
_refCountedProviders.Providers = [.. _refCountedProviders.Providers, provider];
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
Give the provider lists an initial capacity so
List<T>does not reallocate its backing array while it grows in the Microsoft.Extensions.Configuration APIs.Changed:
Benchmark
Benchmark source