[Proposal] Efficient Dictionary Initialization #109029
Labels
api-suggestion
Early API idea and discussion, it is NOT ready for implementation
area-System.Collections
needs-further-triage
Issue has been initially triaged, but needs deeper consideration or reconsideration
Milestone
Proposal: Efficient Dictionary Initialization
Background and motivation
Many applications initialize dictionaries during startup or object instance creation, i.e. mapping strings to integer IDs, or mapping integer IDs to types. At present, the initialization of these containers will generate IL for each key-value pair, either to invoke the
Add
method (when using a dictionary initializer i.e.new () { {k, v} }
) or to initialize each element of aKeyValuePair[]
array. If the dictionary is large enough, this can produce huge methods that strain the limits of the JIT, AOT compiler, or interpreter - increasing both startup/build time and memory usage.At present modern C# has support for efficient initialization of simple constant arrays i.e.
int[]
usingRuntimeHelpers.InitializeArray
andRuntimeHelpers.CreateSpan
. Unfortunately, this support does not apply toKeyValuePair<K, V>[]
, which means there is no efficient way to initialize simple constant dictionaries. Relying onKeyValuePair
also makes it difficult to optimize cases where only the keys or values are constant instead of both - a common scenario.By adding a standardized way to efficiently initialize dictionary types to the BCL we can enable potential language and compiler improvements in this area in addition to giving customers an easy way to improve their startup performance.
API Proposal / Usage
We add a new method to
Dictionary
and (potentially)ConcurrentDictionary
:Which could be used like so:
Extended motivation
As mentioned above, there are common scenarios where all of a dictionary's keys or values may be constant, but not both the keys and values are constant. By splitting the keys and values into separate spans, we can take advantage of initialization optimizations for whichever of the two sequences is constant and only programmatically initialize the other sequence at runtime.
Unresolved questions
Dictionary
with a similar signature?AddRange
operation?Risks
For the current
new () { {key1, value1}, {key2, value2}, ... }
, because it generatesAdd
method calls, the expressionkey2
could have a dependency on global state when it is evaluated, and theAdd(key1, value1)
operation could have side effects that influence the result of the secondAdd
call. In that scenario, using this new initialization API would produce a different result. I believe this is not a problem, since the same would apply to the existingAddRange
.The text was updated successfully, but these errors were encountered: