性能超四倍的高性能.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倍! 网易副总裁.网易杭州研究院执行院长兼网易数帆总经理汪源: 基础软件的能力 ...
随机推荐
- python+request+unittest+HTMLTestRunner
https://www.imooc.com/article/details/id/20813 https://www.cnblogs.com/fennudexiaoniao/p/7771931.htm ...
- AtCoder Grand Contest 017 (VP)
contest link Official Editorial 比赛体验--之前做题的时候感觉 AtCoder 挺快的,现在打了VP之后发现还是会挂的--而且不是加载缓慢或者载不出来,直接给你一个无法 ...
- 八、git学习之——忽略特殊文件、配置别名、搭建git服务器
原文来自 一.忽略特殊文件 有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files . ...
- 下载hotspot源码
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/tags 比如jdk8u262-ga ,最右边可以找到它的id,就是1c6e1f187fdc,下载地址: ...
- Electron安装打包指南
当前环境Debian Linux-Deepin 安装Node 直接下载 命令下载 下载 wget https://nodejs.org/dist/v14.15.1/node-v14.15.1-linu ...
- centos 7.0下安装MySQL 5.7.26
1.下载MySQL 5.7.26安装包,卸载自带MySQL数据库 yum remove mariadb-libs -y yum install -y libaio-devel 2.上传MySQL 5. ...
- ASP .Net Core 中间件的使用(一):搭建静态文件服务器/访问指定文件
前言 随着Asp .Net Core的升级迭代,很多开发者都逐渐倾向于.net core开发. .net core是一个跨平台的应用程序,可以在windows.Linux.macOS系统上进行开发和部 ...
- mybatis默认返回类型
在mybatis中,无论你指定还是不指定返回类型,mybatis都会默认的先将查询回的值放入一个hashMap中(如果返回的值不止一条就是一个包含hashMap的list).这其中的区别在于,如果你指 ...
- 怎么确定一个Flink job的资源
怎么确定一个Flink job的资源 Slots && parallelism 一个算子的parallelism 是5 ,那么这个算子就需要5个slot, 公式 :一个算子的paral ...
- Python基础编程——数据类型
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 在程序设计和编程中,会涉及到各种各样的数据类型,而不同的数据类型变量之间可以进行的运算是不同的.在p ...