【发布时间】:2020-02-20 13:48:40
【问题描述】:
我正在使用来自 TcpClient 的 Json,为了获得低分配和良好性能的解决方案,我决定使用新的 System.IO.Pipelines 处理 IO 和 System.Text.Json 进行反序列化。管道的输出是ReadOnlySequence<byte>。当ReadOnlySequence 中只有一个段时我没问题,这样我就可以将这个段(即ReadOnlySpan<byte>)传递给反序列化器。但是我应该如何处理多个细分?
到目前为止,我所拥有的是下面的代码。但是在某些情况下,序列的长度太大,所以我在stackalloc 中得到了堆栈溢出。此外,在我看来,制作数据副本违反了 System.IO.Pipelines 的意图。 System.Text.Json.JsonSerializer.Deserialize 不应该有 ReadOnlySequence 过载吗?关于如何解决这个问题的任何建议?
private void ProcessLine(ReadOnlySequence<byte> sequence)
{
if (sequence.IsSingleSegment)
{
_result = JsonSerializer.Deserialize<MyType>(sequence.FirstSpan, _jsonSerializerOptions);
}
else
{
Span<byte> stackSpan = stackalloc byte[(int)sequence.Length];
sequence.CopyTo(stackSpan);
_result = JsonSerializer.Deserialize<MyType>(stackSpan, _jsonSerializerOptions);
}
}
【问题讨论】:
-
旁注:在不检查长度的情况下做某事的
stackalloc,首先是小的有点危险;如果我出于某种原因需要对数据进行线性化,我只会在检查长度为<= 512之后使用stackalloc。对于较大的有效载荷如果你需要线性化(你不在这里),你应该从ArrayPool<byte>.Shared租一个超大的数组,在超大的数组上创建一个合适大小的跨度,复制到那个并消耗它,并将数组返回到池中
标签: c# json .net-core system.text.json system.io.pipelines