-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
System.Text.Json 5.x preview deserialization is slower than Newtonsoft when using Stream scenarios on Xamarin platforms #41089
Comments
Yes please share your app so that we can try to repro your numbers. |
The likely reason perf is slower in STJ is in these cases is because STJ uses standard reflection Invoke, not Emit, for the netstandard (non-inbox) configurations. Newtonsoft instead uses compiled expressions trees which are netstandard-compatible but also brings in the very large System.Linq.Expressions.dll so there a disk_size+memory_usage+startup_time vs throughput tradeoff here. It is possible to add support for S.Linq.Expressions if we decide it's worth the tradeoff in these non-inbox scenarios. However, for 6.0 we are also looking at alternate ways to get\set properties and call constructors that do not use Emit but are just as fast, plus we plan on having a code-gen solution that will generate AOT code per POCO type to get\set properties and call ctors that avoids the need for Emit\Reflection entirely. |
@steveharter Is that going to be a new CLR feature? I am interested because it should benefit many projects which now depend on Emit for performance. |
With JSON source generation, we're able to generate code that statically invokes type members without reflection, so this perf issue should be mitigated. It would be good to take measurements that verify this. This work won't stop the .NET 6 release, so I'll move this issue to .NET 7. |
@layomia I have updated my small test app to latest versions of Newtonsoft, Xamarin and .NET 6.0.0-preview.6.21352.12. And things are looking a bit better. On an iPhone12 with iOS, I now consistently see that System.Text.Json is 15-20% faster - previously the performance was roughly the same. On a Samsung phone SM-A505FN, the performance is now roughly the same, sometimes 3-5% faster, sometimes 3-5% slower. However, on a Samsung tablet SM-T510, it is still consistently 30 - 40% slower. So while this certainly is better, there still seems to be room for improvement, at least on certain Android devices. |
@klogeaage thanks for the feedback! Did you try using the JSON source generator for your tests? https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-source-generator/ |
@layomia I have now updated my test with the new On iOS, the picture is the same: it is consistently ~43% faster than NewtonSoft. These results of course also mean it is much faster than Your blog entry was very thorough and well laid out. However, I have a few things that you might consider for a future update:
Since this is so easy to add to a solution using |
Description
I have found that if you use Newtonsoft's ability to deserialize from a
Stream
via itsJsonTextReader()
, then on some platforms, it is comparable to or even better than System.Text.Json. This is not the stated goal of your efforts.So a typical case is deserializing the result of a HTTP call, which in Newtonsoft should be done like this:
While with System.Text.Json the deserializing part will be:
I have found the performance to be roughly the same on iOS devices and MUCH slower (25-40%) on Android. But even equal performance is not the goal, I presume.
I don't know of a unit testing framework that would let me verify this, especially on real physical devices, which may have quite different characteristics than emulators.
So I have created a small Xamarin.Forms app to measure this, which I will be happy to share with you if you find it relevant.
I used another app of mine to share screen shots of the results.
Configuration
Data
In my app, I store a JSON payload from a real world domain model of 526 KB. It is deserialized 5 times and the average is returned for the two serializers.
If can measure that the performance of this is 3-7% slower on the iOS device and 25-40% slower on the Android device. On simulators, I get similar results.
The text was updated successfully, but these errors were encountered: