我们刚刚对序列化器进行了内部研究,以下是一些结果(也供我将来参考!)
Thrift = 序列化 + RPC 堆栈
最大的不同是 Thrift 不仅仅是一个序列化协议,它是一个完整的 RPC 堆栈,就像现代的 SOAP 堆栈。所以在序列化之后,对象可以(但不是强制的)通过 TCP/IP 在机器之间发送。在 SOAP 中,您从一个完整描述可用服务(远程方法)和预期参数/对象的 WSDL 文档开始。这些对象是通过 XML 发送的。在 Thrift 中,.thrift 文件完整地描述了可用的方法、预期的参数对象,并且对象通过可用的序列化器之一进行序列化(使用Compact Protocol,一种高效的二进制协议,在生产中最流行)。
ASN.1 = 爷爷
ASN.1 是由电信人员在 80 年代设计的,与 CompSci 人员最近出现的序列化程序相比,由于库支持有限,使用起来尴尬。有两种变体,DER(二进制)编码和 PEM(ascii)编码。两者都很快,但 DER 速度更快,并且两者的尺寸效率更高。事实上,ASN.1 DER 可以轻松地跟上(有时甚至击败)在其设计之后 30 年 设计的序列化程序,这证明了它的精心设计的设计。它非常紧凑,比 Protocol Buffers 和 Thrift 更小,仅被 Avro 击败。问题在于有很好的库需要支持,现在 Bouncy Castle 似乎是 C#/Java 最好的库。 ASN.1 是安全和加密系统的王者,不会消失,所以不要担心“未来的证明”。找个好图书馆就好了……
MessagePack = 中间包
它还不错,但它既不是最快的,也不是最小的,也不是最好的支持。没有生产理由选择它。
常见
除此之外,它们非常相似。大多数是基本TLV: Type-Length-Value 原则的变体。
Protocol Buffers(源自 Google)、Avro(基于 Apache,用于 Hadoop)、Thrift(源自 Facebook,现在是 Apache 项目)和 ASN.1(源自电信)都涉及某种级别的代码生成,您首先在其中表达数据以特定于序列化程序的格式,然后序列化程序“编译器”将通过code-gen 阶段为您的语言生成源代码。然后,您的应用程序源将这些 code-gen 类用于 IO。请注意,某些实现(例如:Microsoft 的 Avro 库或 Marc Gavel 的 ProtoBuf.NET)允许您直接装饰您的应用程序级别的 POCO/POJO 对象,然后该库直接使用这些装饰的类而不是任何代码生成的类。我们已经看到这提供了性能提升,因为它消除了对象复制阶段(从应用程序级别的 POCO/POJO 字段到代码生成字段)。
一些结果和一个可以玩的现场项目
这个项目 (https://github.com/sidshetye/SerializersCompare) 比较了 C# 世界中的重要序列化程序。 Java 人已经有something similar。
1000 iterations per serializer, average times listed
Sorting result by size
Name Bytes Time (ms)
------------------------------------
Avro (cheating) 133 0.0142
Avro 133 0.0568
Avro MSFT 141 0.0051
Thrift (cheating) 148 0.0069
Thrift 148 0.1470
ProtoBuf 155 0.0077
MessagePack 230 0.0296
ServiceStackJSV 258 0.0159
Json.NET BSON 286 0.0381
ServiceStackJson 290 0.0164
Json.NET 290 0.0333
XmlSerializer 571 0.1025
Binary Formatter 748 0.0344
Options: (T)est, (R)esults, s(O)rt order, (S)erializer output, (D)eserializer output (in JSON form), (E)xit
Serialized via ASN.1 DER encoding to 148 bytes in 0.0674ms (hacked experiment!)