c# Protobuf怎么做到0分配内存的序列化

  介绍

小编给大家分享一下c# Protobuf怎么做到0分配内存的序列化,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!

题目很简单,就是IMessage对象怎么变成Byte []

答案1:

msg.ToByteArray ()

这肯定不符合我们的要求

答案2:

using  var  memoryStream =, new  MemoryStream ();   时间=using  var  codedOutputStream  new  CodedOutputStream (memoryStream);   msg.WriteTo (codedOutputStream);   codedOutputStream.Flush ();   memoryStream.ToArray ();

这里面memoryStream, codedOutputStream,还有ToArray都产生了一个对象,memoryStream内部还会多产生一个byte[]对象

不符合要求

答案3:

有人说你可以给memoryStream传递一个byte[]片,让memoryStream直接用byte []

var  bytes =, new 字节(msg.CalculateSize ());   时间=using  var  memoryStream  new  MemoryStream ();   时间=using  var  codedOutputStream  new  CodedOutputStream (memoryStream);   msg.WriteTo (codedOutputStream);   codedOutputStream.Flush ();

这次消息直接被序列化到字节里面去了,但是memoryStream对象,codecOutputStream还有memoryStream内部的byte[]都还在,我就序列化了一个对象,却产生了3个垃圾对象,

所以,来仔细看看CodedOutputStream类:

///, & lt; summary>   ,,,///,Creates  a  new  CodedOutputStream  that  writes  directly 用,   ,,,///,byte 数组只If  more  bytes 断开连接;written  than  fit 拷贝,数组,   ,,,///,OutOfSpaceException  will  be 抛出。   ,,,///,& lt;/summary>   ,,,public  CodedOutputStream (byte [], flatArray),:,这(flatArray, 0, flatArray.Length)   ,,,{   ,,,}      ,,,///,& lt; summary>   ,,,///,Creates  a  new  CodedOutputStream  that  writes  directly 用,   ,,,///,byte  array 片只If  more  bytes 断开连接;written  than  fit 拷贝,数组,   ,,,///,OutOfSpaceException  will  be 抛出。   ,,,///,& lt;/summary>   ,,,private  CodedOutputStream (byte[],缓冲区,,int 抵消,,int 长度)   ,,,{   ,,,,,this.output =,空;   ,,,,,this.buffer =,缓冲;   ,,,,,this.position =,抵消;   ,,,,,this.limit =, offset  +,长度;   ,,,,,leaveOpen =,真的,,//,Simple  way  of  avoiding  trying 用dispose  of  a  null 参考   ,,,}

提供了一个byte[]的构造函数,但是没提供切片的构造函数,好在有一个私有的构造函数

答案4:

这边就不写代码了,大概意思就是通过反射私有构造函数来构造一个CodedOutputStream对象,来省掉MemoryStream和他内部的byte []

现在离答案已经比较接近了,

那我们的问题是,能不能连CodedOutputStream也省掉呢?

答案5来了:

经过仔细观察,发现这个类没有使用流的情况下,就只需要修改缓冲区,限制,和位置几个成员就行了,虽然是私人成员,但是c#还是能修改

下来立马实践

delegate  void  ClearCodedOutputStream (CodedOutputStream 流,byte[],缓冲区,,int 抵消,,int 数);   ,,,static  ClearCodedOutputStream  ResetCodedOutputStream;   ,,,static  CodedOutputStream  CodedOutputStream =, new  CodedOutputStream (new 字节[10]);      ,,,static  unsafe  void 编码(IMessage 味精,byte[],缓冲区)   ,,,{   ,,,,,ResetCodedOutputStream (codedOutputStream,缓冲区,,0,,buffer.Length);   ,,,,,msg.WriteTo (codedOutputStream);   ,,,,,codedOutputStream.Flush ();   ,,,}      ,,,static  Action, MakeSetter (FieldInfo 字段)   ,,,{   ,,,,,DynamicMethod  m =, new  DynamicMethod (   ,,,,,,,“setter",, typeof(空白),new 类型[],{,typeof (T) typeof (TValue),},, typeof(程序));   ,,,,,ILGenerator  cg =, m.GetILGenerator ();      ,,,,,cg.Emit (OpCodes.Ldarg_0);   ,,,,,cg.Emit (OpCodes.Ldarg_1);   ,,,,,cg.Emit (OpCodes.Stfld,字段);   ,,,,,cg.Emit (OpCodes.Ret);      ,,,,,return  (Action) m.CreateDelegate (typeof (Action));   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

c# Protobuf怎么做到0分配内存的序列化