This repository was archived by the owner on Jan 23, 2023. It is now read-only.
[release/3.1] Populate non-immutable collections directly on deserialize (#41482) #42009
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Ports #41482 to 3.1:
Description
This PR improves performance collections previously deserialized with the use of enumerable/dictionary converters (not to be confused with the
JsonConverterfeature). This includes types derived from native (System.Collections[.Generic]) collections, and native collections that don't implementIList,IDictionary, orIDictionary<>.Converter usage is now removed for collections, excluding non-immutable types and arrays. This usage involved allocating a temporary list or dictionary to store elements of a given collection when deserializing, then passing the temp list to a converter tasked with creating and populating a return type. Converters could be removed because these types could be populated either with manual casts to
ILIst,IDictionary, orIDictionary<>(IList.Add or dictionary indexer), or with a delegate to an add method retrieved and bound with reflection.We get reduced allocations with the elimination of the temp buffers, and faster execution with simplified runtime information detection (including removing logic concerning the assignment of converters to types). See #41482 (comment) for detailed perf improvements.
See the description of #41482 for the rules governing the deserialization of collections.
Customer Impact
Significant perf improvements (ranging from 3-29% faster, up to 34.18% decrease in allocations) for custom derived collections.
Fixes https://github.com/dotnet/corefx/issues/41427 - higher order inheritance for derived types is now supported
Fixes https://github.com/dotnet/corefx/issues/40479 - reflection is now used to support more types, including non-generic Stack and Queue.
Fixes https://github.com/dotnet/corefx/issues/41034 - types that implement IDictionary are now supported for serialization, examples are Hashtable, and SortedList.
Regression?
Performance
There are no significant perf regressions accompanying the perf gains detailed in #41482 (comment).
Deserialization support
This PR is concerned with deserialization of collections. There are no functional changes to how non-collection types work, so there is little chance of rescinding support for these types.
There's a chance that this PR rescinds deserialization support for unknown collections (e.g. user types). However, I feel confident enough for this to go into preview because:
Serialization support
Beside removing checks for the
IDictionaryConstructibleclass types (which are now regarded simply asDictionarytypes), this change doesn't modify the serialization code paths, so it's unlikely for the serializer to stop supporting any previously supported types.Risk
The risk of this PR is described in the regression section. I'll be paying close attention to incoming issues to mitigate as needed.