C# Protobuf如何做到0分配内存的序列化/反序列化(2)
受限于当时的基础设施, 只能做到这样的程度: C# Protobuf如何做到0分配内存的序列化
但是Protobuf 3.13开始提供对Span的支持, 就意味着可以真正做到0分配内存, 对GC非常友好:
- Add
ParseFrom(ReadOnlySequence<byte>)method to enable GC friendly
parsing with reduced allocations and buffer copies. (#7351) - Add support for serialization directly to a
IBufferWriter<byte>or
to aSpan<byte>to enable GC friendly serialization.
The new API is available as extension methods on theIMessagetype. (#7576)
Protobuf 3.14也修改了ByteString:
- annotate ByteString.CopyFrom(ReadOnlySpan) as SecuritySafeCritical (#7701)
代码的例子也很简单:
//反序列化 var span = new ReadOnlySequence<byte>(array); var message = MessageTest.Parser.ParseFrom(span); //序列化 var outputSpan = new Span<byte>(destArray, 0, message.CalculateSize()); message.WriteTo(outputSpan);
需要安装Protobuf 3.14.0以上版本
我们的测试代码, 序列化反序列化1W次, 看看内存分配:
static void Main(string[] args)
{
var array = new byte[0];
var destArray = new byte[1024];
for (int i = 0; i < 10000; ++i)
{
var span = new ReadOnlySequence<byte>(array);
var message = MessageTest.Parser.ParseFrom(span);
message.L1 = 1112121;
message.L2 = 231243452324234;
var outputSpan = new Span<byte>(destArray, 0, message.CalculateSize());
message.WriteTo(outputSpan);
}
}
然后sampling的结果:

只有那个反序列化的对象是被new出来的, 就是我们想要的效果, 建议都升级一下.

浙公网安备 33010602011771号