dylan
December 4, 2018, 10:26pm
1
Demis, I just wanted to hear what your thoughts are on Net Core 3’s work on JSON parsers. Does this help with anything perf related for ServiceStack.Text in the future?
opened 09:45PM - 29 Oct 18 UTC
closed 11:32PM - 31 Jan 20 UTC
area-Meta
JSON has become an essential part of virtually all modern .NET applications and … in many cases even surpassed the usage of XML. However, .NET hasn't had a (great) built-in way to deal with JSON. Instead we've relied on [Json.NET] which continues to serve the .NET ecosystem well.
[Json.NET]: https://www.newtonsoft.com/json
Moving forward, we plan on making some changes to our JSON support:
* **We need high-performance JSON APIs**. We need a new set of JSON APIs that are highly tuned for performance by using `Span<T>` and allows for processing UTF-8 directly without having to transcode to UTF-16 `string` instances. Both aspects are critical for our web server Kestrel, where throughput is a key requirement.
* **Remove dependency from ASP.NET Core to Json.NET**. Today, ASP.NET Core has a dependency on Json.NET. While this provides a tight integration between ASP.NET Core and Json.NET, it also means that application developers cannot freely choose which JSON library they are using. This is also problematic for customers of Json.NET as the version is dictated by the underlying platform. However, Json.NET is frequently updated and application developers often want to -- or even have to -- use a specific version. Thus, we want to remove the dependency from ASP.NET Core 3.0 to Json.NET so that customers can choose which version to use, without fearing they might accidentally break the underlying platform. In addition, this makes it also possible to plug-in an entirely different JSON library.
* **Provide an ASP.NET Core integration package for Json.NET**. Json.NET has basically become the Swiss Army knife of JSON processing in .NET. It provides many options and facilities that allow customers to handle their JSON needs with ease. We don't want to compromise on the Json.NET support customers are getting today, for example, the ability to configure the JSON serialization via the `AddJsonOptions` extension method. Thus, we want to provide the Json.NET integration as a NuGet package that developers can optionally install so they get all the bells and whistles they get from Json.NET today. The other part of this work item is to ensure we have the right extension points so that other parties can provide similar integration packages for their JSON library of choice.
Below are more details around this plan.
## The need for high-performance JSON APIs
The requirements for the .NET stack have changed a bit since the arrival of .NET Core. Historically, .NET has valued usability and convenience. With .NET Core, we've added a focus on performance, and we've made significant investments to serve high performance needs. And the [improvements we made][techempower] in the popular TechEmpower benchmark are a testament to that.
[techempower]: https://www.techempower.com/blog/2016/11/16/framework-benchmarks-round-13/
With .NET Core 2.1, we've added a brand new primitive called [Span\<T>][span-msdn] that allows us to represent native memory and arrays in a uniform way. With this type, we've also added a set of parsing and encoding APIs that are much more memory efficient without having to resort to unsafe code.
[span-msdn]: https://msdn.microsoft.com/en-us/magazine/mt814808.aspx
Part of the work of minimizing allocations is to avoid having to transcode UTF-8 payloads into UTF-16 strings, purely for parsing reasons. Currently, Json.NET is implemented by reading UTF-16. We need the ability to read (and write) JSON documents directly in UTF-8 because most network protocols (including HTTP) use UTF-8.
During .NET Core 2.1 we've learned that updating our existing APIs to leverage `Span<T>` has limits. While we did add a bunch of overloads that accept spans, we also had to produce brand new APIs that are designed around minimizing allocations and dealing with buffers, which we exposed in `System.Buffers` namespaces. And with `System.IO.Pipelines` we've also added a programming model that enables developers to share buffers without having to deal with lifetime issues.
Based on these experiences we believe in order to support JSON parsing, we'll need to expose a new set of JSON APIs that are specifically geared for high-performance scenarios.
You might wonder why we can't just update Json.NET to include support for parsing JSON using `Span<T>`? Well, James Newton-King -- the author of Json.NET -- has the following to say about that:
> Json.NET was created over 10 years ago, and since then it has added a wide range of features aimed to help developers work with JSON in .NET. In that time Json.NET has also become far and away NuGet's most depended on and downloaded package, and is the go-to library for JSON support in .NET. Unfortunately, Json.NET's wealth of features and popularity works against making major changes to it. Supporting new technologies like `Span<T>` would require fundamental breaking changes to the library and would disrupt existing applications and libraries that depend on it.
>
> Going forward Json.NET will continue to be worked on and invested in, both addressing known issues today and supporting new platforms in the future. Json.NET has always existed alongside other JSON libraries for .NET, and there will be nothing to prevent you using one or more together, depending on whether you need the performance of the new JSON APIs or the large feature set of Json.NET.
## Move Json.NET integration into a separate NuGet package
Today, you cannot use ASP.NET Core without Json.NET because it is a dependency of ASP.NET Core itself. Over the years, we've received feedback that the dependency can conflict with other libraries that have their own dependency on a different version of Json.NET. In the past, we've considered addressing this issue by using a private copy of Json.NET in ASP.NET. However, this would create problems when developers want to configure Json.NET (for instance, in order to control how the serializer behaves when formatting JSON objects).
Moving forward we'd like to:
1. Replace the internal usage of Json.NET in ASP.NET Core by the new platform-provided JSON APIs.
2. Factor the public facing usage of Json.NET into an optional integration package that can be acquired from NuGet.
So the existing integration between ASP.NET Core and Json.NET will continue to be supported, but will be moving out of the platform and into a separate package. However, since the integration is then designed to sit on top of the platform, it will also allow customers to update Json.NET to later versions.
Furthermore, customers who need more performance can also choose to use the new JSON APIs, at the expense of the rich feature set that Json.NET offers.
Today, we are announcing .NET Core 3 Preview 1. It is the first public release of .NET Core 3. We have some exciting new features to share and would love your feedback. You can develop .NET Core 3 applications with Visual Studio 2019 Preview 1,
mythz
December 5, 2018, 5:17am
2
It’s a completely different library, it has no impact on any other JSON implementation.
What we don’t know yet is how much faster it will be, whether it will end up supporting .NET Framework/.NET Standard as well, whether it’s feasible in making it substitutable, how different the wire format will be, how well it supports different data types vs SS.Text and whether it’s extensible to be able to support different SS.Text customizations/features.
Basically I don’t know what the strategy will be until it’s released and I’m able to assess it properly.
Rob
December 5, 2018, 9:07am
3
It’s Json.NET - from NewtonSoft. The library has been around for some time and offers comparable speed to ServiceStack. Some benefits here, some benefits there, but all in all it’s just a matter of personal taste afaict.
As long as the json (de)serializer of ServiceStack is fast as hell - including Span support (which really leverages memory use, minimal block copies and CPU usage) there is no reason to switch.
mythz
December 5, 2018, 9:17am
4
It’s an alternative to JSON.NET , they’re developing a new perf-focused UTF8 JSON Serializer, as it’s UTF8-only they can use similar techniques that make Utf8Json fast.
But it’s still early and there’s a lot of unknowns, primarily it’s unclear if they will support .NET Framework and how extensible it will be and whether it will be possible to implement existing SS.NET features that Service Clients need.