Skip to content

Add [JsonConstructor] and support for deserializing with parameterized ctors #33444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 20, 2020

Conversation

layomia
Copy link
Contributor

@layomia layomia commented Mar 10, 2020

Fixes #29895.

Implements specification in #33095.

Performance notes

Benchmarks: dotnet/performance#1233.

TLDR

  • There's a ~4% regression for existing benchmarks when deserializing type graphs with numerous parameterless ctors (specifically IndexViewModel and MyEventListerViewModel benchmarks). There's also a ~300B increase in allocs for these cases. This is due to new state added to the ReadStack to support this feature, and a minimal check when pushing/popping stack frames to support fetching ctor arg state on continuation and/or scenarios involving nested objects with parameterized ctors.
  • There's a minimum alloc cost of 200B when deserializing objects with parameterized ctors, compared to deserializing the same object using parameteless ctors (baseline), assuming all members are deserialized in both cases. Total alloc increase depends on the number of ctor args, and how many of them are value types.
  • Deserialization of "immutable" objects (where every JSON property maps with a ctor arg) with parameterized ctors is 0-15% slower than baseline. Smaller object graphs are slower due to the overhead of setting up a cache for the arguments.
  • Deserialization of mutable objects (where some JSON properties map to object members) with is 0-67% slower than baseline. The slowest cases are when there are numerous object members to deserialize. This is due to re-reading JSON properties after ctor args are parsed and the object is constructed.

@layomia layomia added this to the 5.0 milestone Mar 10, 2020
@layomia layomia self-assigned this Mar 10, 2020
@Dotnet-GitSync-Bot
Copy link
Collaborator

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@steveharter
Copy link
Contributor

Benchmarks: dotnet/performance#1233.

Does this degrade perf on the existing benchmarks?

@layomia
Copy link
Contributor Author

layomia commented Mar 12, 2020

Perf results for existing benchmarks:

Slower diff/base Base Median (ns) Diff Median (ns) Modality
ReadJson_MyEventsListerViewModel>.Deseriali 1.04 310442.18 321704.47
ReadJson_IndexViewModel>.DeserializeFromUtf 1.03 28564.95 29388.81
ReadJson_LoginViewModel>.DeserializeFromUtf 1.02 446.58 457.27
ReadJson_LargeStructWithProperties>.Deseria 1.02 1151.79 1177.42
Faster base/diff Base Median (ns) Diff Median (ns) Modality
ReadJson_SimpleStructWithProperties>.Deseri 1.02 332.89 325.23

before.zip
after.zip

@layomia
Copy link
Contributor Author

layomia commented Mar 13, 2020

About how much faster is it to remember the reader state instead of just doing a full re-read on the second pass?

  • for "immutable" objects where all the JSON properties map to ctor args, it's about the same
  • for small objects (2-4 properties) where about half of the JSON properties map to ctor args, ~25% faster
  • for objects with ~8 properties where about half of the JSON properties map to ctor args, ~11% faster

current.zip
two_pass.zip

@layomia
Copy link
Contributor Author

layomia commented Mar 20, 2020

Test failure unrelated - System.Xml.RW.XmlConvert.Tests.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JsonSerializer support for immutable classes and structs.
4 participants