Uh oh!
There was an error while loading. Please reload this page.
Defer unused CoreLib cache initialization - #132576
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
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-system-globalization |
There was a problem hiding this comment.
Pull request overview
This PR defers initialization of two rarely-needed CoreLib caches by moving them behind nested static holder types, allowing NativeAOT trimming to omit the cache initialization (and related dependencies) when those paths aren’t used.
Changes:
- Move the
EncodingTablename→codepageConcurrentDictionaryinto a nested static holder to avoid initializing it unlessGetCodePageFromNameis called. - Move the ICU-only
CompareInfoSearchValues<char>initialization into a nested static holder to avoid creating it unless the ASCII fast-path is exercised.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Private.CoreLib/src/System/Text/EncodingTable.cs | Defers ConcurrentDictionary<string,int> construction until GetCodePageFromName is invoked. |
| src/libraries/System.Private.CoreLib/src/System/Globalization/CompareInfo.Icu.cs | Defers ICU ASCII SearchValues<char> creation until the ordinal helper methods need it. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
tannergooding
commented
Aug 20, 2026
A sibling to #132550. Just did some local analysis for obvious static constructor roots that looked unnecessary -- CC. @MichalStrehovsky, @jkotas, @agocke this is a trivial improvement that's likely worth taking for .NET 11/12, but it also feels like a more general issue and is a really common pattern in how we and the broader ecosystem write code. This is likely worth explicitly handling in the linker, either via some explicit trimming support or a way (maybe even an attribute) to indicate we support it being "outlined" by the tooling into such helper shapes. We shouldn't have to explicitly think that every unique |
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
tannergooding
commented
Aug 20, 2026
Updated everything and savings measured locally are still the same. |
Moves the ICU-only
CompareInfosearch values and theEncodingTablename cache behind nested static holders. This preserves one-time initialization when those paths are used while allowing NativeAOT to trim them from applications that only need unrelated static state.A locally built Release NativeAOT
win-x64Hello World withInvariantGlobalization=truemeasured:mainCompareInfoholderThe cumulative raw section changes are
.text-12,800 bytes,.rdata-9,728 bytes,.data-1,024 bytes,.pdata-512 bytes, and.reloc-512 bytes. The final dependency graph no longer containsSearchValues.Create,EncodingTable::.cctor, or theConcurrentDictionary<string, int>name-cache construction.Note
This pull request was prepared with GitHub Copilot.