什么是 MessagePack
MessagePack 是一种高效的二进制序列化格式,旨在以紧凑的形式表示结构化数据。它类似于 JSON,但通过二进制编码实现了更小的数据体积和更快的序列化/反序列化速度。
MessagePack for C#
这是一个为C#设计的极快的MessagePack序列化器。
它比MsgPack-Cli快10倍,并且优于其他C#序列化工具。MessagePack for C#还内置了对LZ4压缩的支持——一种非常快速的压缩算法。性能很重要,尤其是在游戏、分布式计算、微服务或数据缓存等应用中。
性能比较图
MessagePack具有紧凑的二进制大小和完整的通用表达数据类型集。请查看与JSON、protobuf、ZeroFormatter的对比部分,了解为什么MessagePack C#是最快的。
安装
这个库通过NuGet分发。也有特殊的Unity支持。
我们以.NET Standard 2.0为目标,并对.NET 8+和.NET Framework进行了特殊优化。
该库代码是纯C#(在某些平台上使用JIT IL代码生成或AOT安全源生成器)。
NuGet包
要通过NuGet安装,只需安装MessagePack包:
Install-Package MessagePack
还有一些官方和第三方扩展包可用 :
Install-Package MessagePack.ReactiveProperty
Install-Package MessagePack.UnityShims
Install-Package MessagePack.AspNetCoreMvcFormatter
快速入门
定义要序列化的结构体或类,并用[MessagePackObject]属性进行注释。
用[Key]属性注释需要序列化的成员(字段以及属性)。
[MessagePackObject]
public class MyClass
{
// Key属性接受一个序列化索引(或字符串名称)
// 值必须唯一并考虑版本控制。
// 键将在后面的章节详细描述。
[Key(0)]
public int Age { get; set; }
[Key(1)]
public string FirstName { get; set; }
[Key(2)]
public string LastName { get; set; }
// 所有不需要序列化的字段或属性必须用[IgnoreMember]注释。
[IgnoreMember]
public string FullName { get { return FirstName + LastName; } }
}
调用MessagePackSerializer.Serialize<T>/Deserialize<T>来序列化/反序列化你的对象实例。
你可以使用ConvertToJson方法获取任何MessagePack二进制blob的人类可读表示。
class Program
{
static void Main(string[] args)
{
var mc = new MyClass
{
Age = 99,
FirstName = "hoge",
LastName = "huga",
};
// 调用Serialize/Deserialize,就是这么简单。
byte[] bytes = MessagePackSerializer.Serialize(mc);
MyClass mc2 = MessagePackSerializer.Deserialize<MyClass>(bytes);
// 你可以将MessagePack二进制blob转储为人可读的JSON。
// 使用索引键(而不是字符串键)将序列化为MessagePack数组,
// 因此没有属性名。
// [99,"hoge","huga"]
var json = MessagePackSerializer.ConvertToJson(bytes);
Console.WriteLine(json);
}
}
默认情况下,需要MessagePackObject注释。这可以通过对象序列化部分和格式解析器部分中的详细信息使其可选。
内置支持的类型
默认情况下,这些类型可以序列化:
- o 原始类型 (int, string 等...)、Enums、Nullable<>、Lazy<>
- o TimeSpan, DateTime, DateTimeOffset
- o Guid, Uri, Version, StringBuilder
- o BigInteger, Complex, Half
- o Array[], Array[,], Array[,,], Array[,,,], ArraySegment<>, BitArray
- o KeyValuePair<,>, Tuple<,...>, ValueTuple<,...>
- o ArrayList, Hashtable
- o List<>, LinkedList<>, Queue<>, Stack<>, HashSet<>, ReadOnlyCollection<>, SortedList<,>
- o IList<>, ICollection<>, IEnumerable<>, IReadOnlyCollection<>, IReadOnlyList<>
- o Dictionary<,>, IDictionary<,>, SortedDictionary<,>, ILookup<,>, IGrouping<,>, ReadOnlyDictionary<,>, IReadOnlyDictionary<,>
- o ObservableCollection<>, ReadOnlyObservableCollection<>
- o ISet<>,
- o ConcurrentBag<>, ConcurrentQueue<>, ConcurrentStack<>, ConcurrentDictionary<,>
- o 不可变集合(如ImmutableList<>等)
- o 具有无参构造函数的ICollection<>或IDictionary<,>的自定义实现
- o 具有无参构造函数的IList或IDictionary的自定义实现
对象类型序列化
StandardResolver 和 ContractlessStandardResolver 可以序列化 object/匿名类型对象。
var objects = new object[] { 1, "aaa", new ObjectFieldType { Anything = 9999 } };
var bin = MessagePackSerializer.Serialize(objects);
// [1,"aaa",[9999]]
Console.WriteLine(MessagePackSerializer.ConvertToJson(bin));
// 支持匿名类型序列化
var anonType = new { Foo = 100, Bar = "foobar" };
var bin2 = MessagePackSerializer.Serialize(anonType, MessagePack.Resolvers.ContractlessStandardResolver.Options);
// {"Foo":100,"Bar":"foobar"}
Console.WriteLine(MessagePackSerializer.ConvertToJson(bin2));
Unity 支持有限。
反序列化时,行为将与动态(未类型化)反序列化相同。
性能
对 MessagePack For C# 与其他序列化器的基准测试是在 Windows 10 Pro x64 Intel Core i7-6700K 4.00GHz, 32GB RAM 上运行的。基准测试代码可以在这里找到 - 以及它们的版本信息。
ZeroFormatter 和 FlatBuffers 有无限快的反序列化器,所以忽略它们的反序列化性能。
image
仓库
https://github.com/MessagePack-CSharp/MessagePack-CSharp