baidu

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 a Span<byte> to enable GC friendly serialization.
    The new API is available as extension methods on the IMessage type. (#7576)

Protobuf 3.14也修改了ByteString:

  • annotate ByteString.CopyFrom(ReadOnlySpan) as SecuritySafeCritical (#7701)

代码的例子也很简单:

1
2
3
4
5
6
7
//反序列化
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次, 看看内存分配:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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出来的, 就是我们想要的效果, 建议都升级一下.

posted @   egmkang  阅读(932)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示