-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Remove the second type parameter from CastingConverter #80755
Remove the second type parameter from CastingConverter #80755
Conversation
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsThe
This PR relaxes the implementation so that cc @eerhardt
|
@@ -138,15 +143,20 @@ internal static bool ShouldFlush(Utf8JsonWriter writer, ref WriteStack state) | |||
// This is used internally to quickly determine the type being converted for JsonConverter<T>. | |||
internal abstract Type TypeToConvert { get; } | |||
|
|||
internal abstract bool OnTryReadAsObject(ref Utf8JsonReader reader, JsonSerializerOptions options, scoped ref ReadStack state, out object? value); | |||
internal abstract bool TryReadAsObject(ref Utf8JsonReader reader, JsonSerializerOptions options, scoped ref ReadStack state, out object? value); | |||
internal abstract object? ReadAsObject(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though this change is adding new methods to JsonConverter
this should increase code size linearly over the number of generic specializations. This should still contribute to a net decrease of code size given that CastingConverter
contributes to quadratic growth over the number of types being used. I will follow up with real numbers validating this hypothesis.
Is it possible to get before/after size numbers for this change? If you need a test app, the one we are using in our perf measurements is here. |
I compared the publish AOT size for the Goldilocks app between main and the PR branch. I'm seeing a ~7MB improvement in the size of the |
STJ Numbers from the mstat dump of the Goldilocks app. Seeing just over 1MB of size reduction overall:
main
PR
|
/benchmark json aspnet-citrine-win libs |
Benchmark started for json on aspnet-citrine-win with libs. Logs: link |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a look over the code (I'm no expert in this area), but I think this is a great change. If there are no runtime perf degradations, I think this is a great NativeAOT size win (5% of the new dotnet new api -aot
app).
json - aspnet-citrine-win
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome win, thanks!
Tagging subscribers to 'size-reduction': @eerhardt, @SamMonoRT, @marek-safar Issue DetailsThe
This PR relaxes the implementation so that
|
The
CastingConverter<TSource, TTarget>
class is an internal adapter used for custom converters whose declared type doesn't match that of the serialized member they are being assigned to. The problem with the current implementation is thatCastingConverter
uses two type parameters, which is contributing to a quadratic explosion of generic specializations in NativeAOT:This PR relaxes the implementation so that
CastingConverter
references and consumes the underlying converter as a weakly typedJsonConverter
instance. This change can regress runtime performance in certain scenaria due to added boxing/virtual calls, but this should only impact members that are using converters polymorphically -- a relatively rare occurrence.cc @eerhardt @jkotas