Newtonsoft.Json
Newtonsoft.Json copied to clipboard
Couldn't Newtonsoft.Json utilize System.Span for more performance?
https://blogs.msdn.microsoft.com/dotnet/2017/11/15/welcome-to-c-7-2-and-span/
Just wondering if altering Newtonsoft.Json to utilize that feature wouldn't result in a significant speedup, since working with strings is really the heavy lifting for Newtonsoft.Json too i would imagine?
IMHO the announcement linked above is somewhat misleading, so hopefully people here won't mind if I add a few details about the current state of spans in .NET.
It is important to know that using spans would be an optimization that's currently only feasible on .NET Core ≥2.1 because, at this time, there is no other .NET platform that fully supports spans.
By "full support", I am referring to three separate requirements:
-
Availability of the base types
Span<T>
,ReadOnlySpan<T>
,Memory<T>
, andReadOnlyMemory<T>
. -
Availability of APIs in the BCL that use the above types. (Without dedicated APIs, spans are about as useful as
System.ArraySegment<T>
—that is, not useful at all.) -
Recognition of the above types by the .NET runtime's JIT compiler for efficient code generation. (Only with runtime support are spans really as "fast" as plain array index or pointer operations. Without runtime support, they might even cause additional overhead.)
Concerning the .NET Framework, you can get (1) via the NuGet package System.Memory
. But you might be out of luck regarding (2) and (3) as the classic .NET Framework will likely never have BCL nor JIT support for spans—see https://github.com/Microsoft/dotnet/issues/770.
Concerning .NET Standard, BCL support for spans is ~~apparently~~ planned for ~~vNext—see https://github.com/dotnet/standard/issues/682#issuecomment-401947585~~ .NET Standard 2.1.
This could be an indication that full span runtime support (3) might eventually make it into platforms other than .NET Core (most notably, Mono and Mono-based runtimes—see e.g. https://github.com/mono/mono/issues/7249).
I am also linking to https://github.com/Tornhoof/SpanJson for those who are interested in seeing spans at work in JSON parsing.
@stakx so (3) indirectly states you should not use aspnetcore 2.1 on .NET Framework although being a valid target. I have not noticed a warning so far that it will be slower than aspnetcore 2.0 when not used on netcore.
@springy76, let's not get too sidetracked here, but... that is interesting. I am not familiar with ASP.NET Core, but assuming that 2.1 makes heavy use of spans, I cannot say how they were able to get it working on top of the .NET Framework. Not so much because of the missing JIT support (3), which would just make it slower, but because of missing BCL APIs (2), which would make it impossible to compile and run.
Anything with span would wait until netstandard3.0 when the Span APIs are available.
Spans are now planned for inclusion in .NET Standard 2.1.
This blog post (and a comment underneath) seems to imply that .NET Framework 4.8 will have the JIT improvements for Span<T>
and similar - though the additional Span<T> APIs (which would then only be available via System.Memory
), and only for 64-bit: https://blogs.msdn.microsoft.com/dotnet/2018/09/17/announcing-net-framework-4-8-early-access-build-3646/
Runtime – JIT improvements The JIT in .NET 4.8 is based on .NET Core 2.1. All bug fixes and many code generation-based performance optimizations from .NET Core 2.1 are now available in the .NET Framework.
Russ Keldorph [MSFT] Only the 64-bit JIT will be based on .NET Core. The 32-bit JIT is not RyuJIT and will remain largely unchanged in .NET 4.8. Sorry for the confusion.
Seeing a lot of libs use span and esp readonlymemory
any updates? is it possible?
@JamesNK
Anything with span would wait until netstandard3.0 when the Span APIs are available.
Span<T>.
ref and ReadOnlySpan<T> Struct
is available in netstandrad2.1
and .Net6 support Deserialize(ReadOnlySpan<Char>) here
It's nice if Newtonsoft.Json can support span.
JsonReader
is not a ref struct so it's not possible to rewrite JSON parsing to use span from the bottom up. For example, it's not possible to add a Deserialize method that takes a span because it can't be stored by JsonReader
.
@JamesNK Thanks for reply. Now it's clear :)