性能超四倍的高性能.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);
序列化到byte数组:
var data = Xfrogcn.BinaryFormatter.BinarySerializer.Serialize(data);
反序列化
从流中反序列化:
var obj = await Xfrogcn.BinaryFormatter.BinarySerializer.DeserializeAsync(stream);
从byte数组反序列化:
var obj = Xfrogcn.BinaryFormatter.BinarySerializer.Deserialize(data);
反序列化为指定类型:
var obj = await Xfrogcn.BinaryFormatter.BinarySerializer.DeserializeAsync<T>(stream);
或者:
var obj = Xfrogcn.BinaryFormatter.BinarySerializer.Deserialize<T>(data);
当然,你也可以在序列化与反序列化时指定不同的配置(),更详细的使用说明请参考[快速开始]
三、注意事项
- 与System.Text.Json的设计一致,由于类型解析、序列化转换器等缓存都是以配置实例为基础,即每一个配置实例的缓存是独立的,故请使用共享的配置实例,请勿为每一次序列化分配新的配置实例
- 在流模式下,默认缓冲区的大小会极大地影响读取性能,请根据实际情况进行详细的测试以获取合适的缓冲区设置(默认设置可适合大多数场景)
开源需要大家的努力,有兴趣的同学,欢迎提交代码,一起完善!
性能超四倍的高性能.NET二进制序列化库的更多相关文章
- 开源!一款功能强大的高性能二进制序列化器Bssom.Net
好久没更新博客了,我开源了一款高性能的二进制序列化器Bssom.Net和新颖的二进制协议Bssom,欢迎大家Star,欢迎参与项目贡献! Net开源技术交流群 976304396,禁止水,只能讨论技术 ...
- 线程安全使用(四) [.NET] 简单接入微信公众号开发:实现自动回复 [C#]C#中字符串的操作 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化 自已动手做高性能消息队列 自行实现高性能MVC WebAPI 面试题随笔 字符串反转
线程安全使用(四) 这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来. 这里主要讲解下CancellationT ...
- Web 应用性能提升 10 倍的 10 个建议
转载自http://blog.jobbole.com/94962/ 提升 Web 应用的性能变得越来越重要.线上经济活动的份额持续增长,当前发达世界中 5 % 的经济发生在互联网上(查看下面资源的统计 ...
- 将Web应用性能提高十倍的10条建议
导读 提高 web 应用的性能从来没有比现在更重要过.网络经济的比重一直在增长:全球经济超过 5% 的价值是在因特网上产生的(数据参见下面的资料).这个时刻在线的超连接世界意味着用户对其的期望值也处于 ...
- 将 Web 应用性能提高十倍的10条建议
提高 web 应用的性能从来没有比现在更重要过.网络经济的比重一直在增长:全球经济超过 5% 的价值是在因特网上产生的(数据参见下面的资料).这个时刻在线的超连接世界意味着用户对其的期望值也处于历史上 ...
- 如何利用缓存机制实现JAVA类反射性能提升30倍
一次性能提高30倍的JAVA类反射性能优化实践 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第4期-支付结算部支付研发团队高级工程师陶红<JAVA类反射技术&优化> ...
- [转载]PayPal为什么从Java迁移到Node.js,性能提高一倍,文件代码减少44%
http://ourjs.com/detail/52a914f0127c763203000008 大家都知道PayPal是另一家迁移到Node.js平台的大型公司,Jeff Harrell的这篇博文 ...
- PayPal为什么从Java迁移到Node.js 性能提高一倍 文件代码减少44%
大家都知道PayPal是另一家迁移到Node.js平台的大型公司,Jeff Harrell的这篇博文 Node.js at PayPal 解释了为什么从Java迁移出来的原因: 开发效率提高一倍(2 ...
- 性能1.84倍于Ceph!网易数帆Curve分布式存储开源
在上周刚结束的网易数字+大会上 网易数帆宣布: 开源一款名为Curve的高性能分布式存储系统, 性能可达Ceph的1.84倍! 网易副总裁.网易杭州研究院执行院长兼网易数帆总经理汪源: 基础软件的能力 ...
随机推荐
- ATT&CK 实战 - 红日安全 vulnstack (一) 靶机渗透
关于部署:https://www.cnblogs.com/Cl0ud/p/13688649.html PS:好菜,后来发现内网主机还是PING不通VM1,索性三台主机全部配成NAT模式,按照WEB靶机 ...
- C语言网络编程(Linux && Windows)(1)
和朋友一起做课程设计,同时学习C语言的网络编程,以前写的都是python网络编程,但python很多的库都是封装好的,大部分人在使用的时候不会去了解底层的实现,这样对长远的学习不太好,也改正自己这方面 ...
- 关于EF框架EntityState的几种状态
在使用EF框架时,我们通常都是通过调用SaveChanges方法把增加/修改/删除的数据提交到数据库,但是上下文是如何知道实体对象是增加.修改还是删除呢?答案是通过EntityState的枚举值来判断 ...
- LeetCode初级算法之数组:122 买卖股票的最佳时机 II
买卖股票的最佳时机 II 题目地址:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/ 给定一个数组,它的第 i ...
- react路由初探(2)
对着官网的例子反正是没有搞出来,所以搜了一大堆,最终搞出来了,记录一下 import React from 'react'; // 首先我们需要导入一些组件... (这个是中文网示例,按这个做,报一大 ...
- bootstrap table 嵌入百分比进度条
- 我对js数据类型的理解和深浅(copy)的应用场景
本人毕业一所专科院校,所学专业是计算机应用技术,在大学时对前端有了一定的了解之后,觉得自己对前端的兴趣十分强烈,开始自学前端,一路上也是坎坎坷坷,也有想要放弃的时候,还好坚持了下来,并且从事前端开发已 ...
- MySQL技术内幕InnoDB存储引擎(六)——锁
什么是数据库的锁? 锁是数据库系统区别于文件系统的一个关键特性.锁机制用于管理对共享资源的并发访问.让数据库事务满足隔离性的要求. InnoDB 中锁的作用 不仅用于对数据进行并发访问,还还包括了缓冲 ...
- linux 下指定配置文件安装mongodb
下载 官网下载地址:https://www.mongodb.com/try/download/community,并上传linux 服务器 二.mongon目录结构下 /data/mongo . lo ...
- eclipse/myeclipse 使用技巧
一.变量名自动补全 原理是:在输入变量名后,去掉按下空格或=后,代码上屏 以前只知道alt+/调出assist,后来发现可以所有字母都激活content assist(8.1里有写).用起来果然很爽, ...