5 ms·
https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/#json https://devblogs.microsoft.com/dotnet/performance_improvemen... This is a really
by fabian2k 4y ago
https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/#json https://devblogs.microsoft.com/dotnet/performance_improvemen...
This is a really interesting, or rather terrifying part of that blog post. I thought I had a reasonably good knowledge about typical performance mistakes in .NET, but I never heard about this particular one.
If I understand it right, initializing a fresh JsonSerializerOptions object before each call to Serialize/Deserialize in System.Text.Json is incredibly expensive. It essentially disables the cache and means the serializer analyzes this case fully every time. And this is more on the order of 100x as expensive than using the cached version, so not a trivial amount.
- kevingadd 4y agoA polite way to describe most serialization tooling in the .NET ecosystem would be "bad". It's unfortunate, but it's good to see improvements happening. I still try to avoid JSON in general on .NET since I've had so many bad experiences with the various JSON libraries out there. Sadly if you want to ship well-performing software in .NET it's still mandatory to run it under a profiler on a regular basis, both to spot frequent unnecessary GC allocations and to spot CPU bottlenecks. Either one would probably catch this particular problem, thankfully! I use the built in VS profilers sometimes, and other times I use Superluminal's excellent CPU profiling.
- aliswe 4y agoStreaming serialization with System.Text.Json doe.
- neonsunset 4y agoMost pitfalls in .NET are luckily along the lines of "punishing people who redo all the steps on each method call or write code Java style" which might even be a good thing. I wonder where does your bad experience with Json libraries come from? Even back in the days of .NET Framework, there was a variety of quality libraries such as Newtonsoft.JSON, Utf8Json or other more interesting but less feature-rich packages. Nowadays, STJ provides quite good defaults and in places where they differ from Newtonsoft, there usually is a reason for that. I'm not saying all APIs are successful, namely, I consider OOB API for source generated serialization to be really user-unfriendly. However, other than that, just don't do unnecessary work and cache stateless objects like serializer settings. This translates to most programming languages and isn't something C# specific.
- kevingadd 4y agoI had a terrible experience with Newtonsoft every time I used it: * compatibility-breaking changes happening without proper versioning, which meant if someone happened to install their copy in the GAC my app would break. I had to start shipping custom builds of Newtonsoft with the version 9.9.9.9 to stop the GAC from breaking me and I never had this problem with any other managed library * Bad performance * The necessity to do awkward things to solve basic serialization problems, like write a custom contract resolver just so that it wouldn't try to write to read-only properties The standard JSON libraries in the BCL at the time were much worse. The new STJ looks alright but after so many bad experiences I can't bring myself to trust it.
- neonsunset 4y agoFor read-only properties/fields, the useful pattern for Newtonsoft is to just provide a parametrized constructor. There are multiple ways to implements this and all of them are well documented. When it comes to performance - are you sure your code doesn't do anything that pessimizes it? Regular JsonConvert.Serialize/.Deserialize work well and are reasonably fast. Obviously, if you use a lot of custom contract revolvers with heavy uncached reflection and large allocations, it will destroy the performance but almost no library can fix bad user-provided implementations, best case is to design API in a way that will nudge towards efficient patterns but that's it. Keep in mind that assumptions, especially brought from different languages, may cause a user to unnecessarily shoot themselves in the foot, especially when they are solved by spending 15 minutes to go over suggested usage patterns in the documentation. In addition, I think it is counter-productive to judge a completely unrelated Json library in BCL by your experience on a limited scenario with Newtonsoft where its defaults were simply different from expectations. The criticism listed is applicable to software that was released about a decade ago, on a platform with features (GAC) that have long become legacy. (e.g. GAC is a very old feature, .netfw 4.6.2 was released 8 years ago, Newtonsoft 9.* - 6 years ago, etc.) I'm not saying all libraries are perfect, but experimenting with implementations in Rust, Java and Swift left me with impression that C# packages are solid and relatively easy to use even not the most popular ones, and DOM-like JObject/JToken were quite nice to use too for untyped payloads. Last but not least, during the days of .NET Framework, the fastest implementation was Utf8Json losing only to optimized binary serializers which had to perform less work, it was nowhere near as popular or as feature-rich as Newtonsoft but in performance-sensitive scenarios it was very nice due to pooling internal buffers, emitting efficient IL stubs for serialization and using many other tricks to reduce overhead as much as possible. Anyway, Utf8Json is sadly deprecated but STJ provides very good performance OOB and if you need even more, SpanJson and SimdJson can give you even better numbers, enjoying newer perf-focused features of the language and research done on JSON serialization. .NET today is much, much better and very different from .NET Framework of 10 years ago. Saying otherwise is not much different behavior from the people who keep yelling "msft bad, closed source windows only garbage!" for whatever reason.
- AtNightWeCode 4y agoYeah, it should be in a static property/field or a singleton. Seen measurable improvements based on fixing this. System.Text.Json really has many unnecessary pitfalls. Maybe they should have fixed the memory problems with Newtonsoft instead. A much more practical lib. Edit: With that said, in most apps JSON speed is very not important. Never seen it consumed more than couple of percent of execution time for APIs since .NET 1.1.
- jayd16 4y agoNewtonsoft isn't AOT friendly though. That's why they went with both.
- AtNightWeCode 4y agoAOT? I really don't understand why they made the transition to System.Text.Json impossible for most projects.