性能超四倍的高性能.NET二进制序列化库

二进制序列化在.NET中有很多使用场景,如我们使用分布式缓存时,通常将缓存对象序列化为二进制数据进行缓存,在ASP.NET中,很多中间件(如认证等)也都是用了二进制序列化。

在.NET中我们通常使用System.Runtime.Serialization.Formatters库中的BinaryFormatter来进行二进制序列化,但此库存在以下缺点:

尽管.net core对BinaryFormatter进行了一些列优化,但其性能还是较低

序列化结果尺寸过大,BinaryFormatter保留了非常详细的类型元数据。

安全问题,BinaryFormatter 因为其强大的功能和易用性而广泛用于整个 .NET 生态系统。 但是,其强大的功能也让攻击者能够影响目标应用内的控制流。 成功的攻击可能导致攻击者能够在目标进程的上下文中运行代码。(可参考此文档)

通过AssemblyLoadContext动态加载程序集可能无法反序列化的问题(比如使用[PluginFactory]插件框架),例如,你在公共库A中封装了序列化辅助方法,在插件程序集B中声明了序列化类型,并通过公共库A中的辅助方法进行序列化或反序列化,最后主程序集C通过独立的AssemblyLoadContext动态加载插件程序集B,此种场景中,B中反序列化时将会引发无法找到程序集的异常。

序列化类,必须通过SerializableAttribute特性进行标注

为了解决这些缺陷,我们开源了一款独立的高性能.NET二进制序列化库Xfrogcn.BinaryFormatter([Github]  [Gitee]),该库参考了System.Text.Json库,通过Span与Emit大大提升了序列化性能。此库目标为.NET Standard 2.1。

Xfrogcn.BinaryFormatter具有以下优点:

高性能,通过Span与Emit大大提升了性能,其性能超过System.Runtime.Serialization.Formatters库的近四倍

更小的序列化尺寸(75%)

简单易用,与System.Text.Json基本一致的API接口。

反序列化时实例引用的维持

支持反序列化到不同的类型

更安全

支持AssemblyLoadContext动态加载程序集中类型的序列化

无需SerializableAttribute特性标注

完善的内置类型支持([支持的类型])

一、性能

与.NET内置的System.Runtime.Serialization.Formatters.Binary.BinaryFormatter二进制序列化对比,性能最高可达到它的4倍以上,而序列化结果的大小仅只有它的75%。

以下为通过test/BinaryFormatter.Benchmark性能测试项目获取的性能数据,其中:

Json指System.Text.Json,可以看到其性能的确强悍

XfrogcnBinary指本库

SystemBinaryFormatter指.NET内置二进制序列化库(System.Runtime.Serialization.Formatters.Binary.BinaryFormatter)

类别Stream为采用流化方式序列化

类别Bytes为直接序列化为Byte数组或从Byte数组反序列化 所有的测试都基于默认配置,(流化方式下默认的缓冲区大小将会明显影响序列化性能)

序列化

序列化

Method   Categories   Mean  
Json   Stream   61.41 μs  
XfrogcnBinary   Stream   92.97 μs  
SystemBinaryFormatter   Stream   291.37 μs  
Json_Bytes   Bytes   59.79 μs  
XfrogcnBinary_Bytes   Bytes   88.67 μs  

 

反序列化

反序列化

Method   Categories   Mean  
Json   Stream   100.12 μs  
XfrogcnBinary   Stream   96.34 μs  
SystemBinaryFormatter   Stream   334.68 μs  
Json_Bytes   Bytes   80.13 μs  
XfrogcnBinary_Bytes   Bytes   92.14 μs  

 

二、如何使用

Xfrogcn.BinaryFormatter库的使用非常简单,基本与System.Text.Json一致:

序列化

序列化到流:

MemoryStream ms = new MemoryStream(); await Xfrogcn.BinaryFormatter.BinarySerializer.SerializeAsync(ms, data);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyyywp.html