Newtonsoft.json: Feature request: async serialization to/from the System.IO.Pipelines API

Created on 12 Aug 2018  路  2Comments  路  Source: JamesNK/Newtonsoft.Json

Newtonsoft.Json has thus far not offered async serialization APIs (I believe) because async APIs incur a perf hit, and because it can be important to not read more bytes than necessary for the top-level JSON token it started reading, which with Stream APIs requires reading one byte at a time (also very slow).

The new System.IO.Pipelines API offers a solution to both these problems. By serializing to a PipeWriter or deserializing from a PipeReader, you can asynchronously wait for more buffers when necessary, but when there are buffers you can read directly from them, with no memory copying at all. And you don't need to worry about reading too far because after reading what you want from the buffer, you can indicate how many bytes you "consumed" and "examined" so that it saves the bytes you didn't use for another read operation later.

Have you looked into this? Would you be open to a PR if I submitted one?

The huge boon IMO for this feature would be that users no longer have to make a choice of being async but buffering the entire message at once before (de)serialization, or being able to stream serialization for lower memory impact but at the cost of blocking a thread during the entire process which may include long I/O waits.

Most helpful comment

How would you feel about a PR that makes your serialization code async (returning ValueTask for better perf) where it hardly ever actually yields, but may occasionally when the buffers need to wait for I/O? I don't anticipate that you'd have code duplication since the sync and async code paths would be implemented with the same methods.

All 2 comments

Writing a JsonReader and JsonWriter that use IBufferWriter<byte> (and whatever the read equivalent is) would certainly be possible. Making the entire serializer async would be a huge amount of work and require a lot of duplication of code to have sync and async paths. I wouldn't really want to maintain that.

I'm not planning to work with pipelines myself right now, I have other things I want to add to the next version first, but a JsonReader and JsonWriter that used them directly would be useful and could live in an independent package.

How would you feel about a PR that makes your serialization code async (returning ValueTask for better perf) where it hardly ever actually yields, but may occasionally when the buffers need to wait for I/O? I don't anticipate that you'd have code duplication since the sync and async code paths would be implemented with the same methods.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MuiBienCarlota picture MuiBienCarlota  路  14Comments

TylerBrinkley picture TylerBrinkley  路  16Comments

davidfowl picture davidfowl  路  49Comments

schani picture schani  路  11Comments

plokin picture plokin  路  12Comments