协议缓冲区有多快?
协议缓冲区的.NET会轻量/比Remoting(SerializationFormat.Binary)更快? 在语言/框架方面是否会有一stream的支持? 即它处理透明像Remoting / WebServices?
我非常怀疑它会有直接的语言支持,甚至是框架支持 – 这种types的东西与第三方库很好地处理。
我自己的Java代码是明确的 – 你必须调用方法来序列化/反序列化。 (有RPC存根将自动序列化/反序列化,但没有RPC实现。)
尽pipeMarc Gravell的项目与WCF非常吻合 – 据我所知,只需要告诉它(一次)使用协议缓冲区进行序列化,其余部分是透明的。
在速度方面,你应该看看Marc Gravell的基准页面 。 我的代码比他的速度要快一些,但是两者比框架中的其他序列化/反序列化选项要快得多。 应该指出的是,协议缓冲区也更加有限 – 它们不会尝试序列化任意types,只有支持的types。 我们将尝试以便携的方式支持更多的常见数据types(十进制,DateTime等)(将来他们自己的协议缓冲区消息)。
一些性能和大小的指标是在这个页面上 。 我目前还没有得到Jon的统计数据,只是因为页面有点老了(Jon:我们必须解决这个问题!)。
重新透明; protobuf-net可以通过合同挂钩到WCF; 请注意,它与MTOM在基本http上的搭配也很好。 但是Silverlight并不适用,因为Silverlight缺less注入点。 如果使用svcutil,则还需要向类中添加一个属性(通过部分类)。
Re BinaryFormatter(远程处理); 是的,这是完全支持; 你可以简单地通过一个简单的ISerializable
实现来完成这个任务(也就是说,只需使用相同的参数来调用Serializer
方法)。 如果你使用protogen
来创build你的类,那么它可以为你做:你可以通过参数在命令行中启用它(默认情况下不启用它,因为BinaryFormatter
不适用于所有的框架[CF等]) 。
请注意,对于本地远程处理(IPC)上的非常小的对象(单个实例等),原始的BinaryFormatter
性能实际上更好 – 但对于非平凡graphics或远程链接(networking远程处理),protobuf-net可以performance得相当好。
我还应该注意协议缓冲区的线格式不直接支持inheritance; protobuf-net可以欺骗这个(同时保留线的兼容性),但是像XmlSerializer一样,你需要预先声明子类。
为什么有两个版本?
我猜,开源的乐趣,我和Jon和我曾经在联合项目上工作过,并且讨论过合并这两个,但事实是它们是针对两种不同的情况:
- dotnet-protobufs (Jon's)是现有java版本的一个端口。 这意味着对于任何已经使用java版本的人来说,它都有一个非常熟悉的API,并且它是build立在典型的java构造(构build器类,不可变数据类等)基础上的,并且有一些C#曲折。
- protobuf-net (Marc's)是一种以相同的二进制格式(实际上,一个关键的要求就是可以在不同格式之间交换数据)重新实现,但是使用典型的.NET惯用法:
- 可变数据类(无build设者)
- 序列化成员细节用属性表示(可比较
XmlSerializer
,DataContractSerializer
等)
如果您正在使用java和.NET客户端,那么对于熟悉的API,Jon可能是一个不错的select。 如果你是纯净的.NET,protobuf-net有其优点 – 熟悉的.NET风格的API,但也有:
- 你并不是被迫成为契约第一(尽pipe你可以,并提供代码生成器)
- 您可以重新使用您现有的对象(事实上,
[DataContract]
和[XmlType]
类通常可以使用而不做任何更改) - 它完全支持inheritance(它通过欺骗封装来实现)(对于协议缓冲区实现可能是唯一的)注意子类必须提前声明)
- 它将无法插入和利用核心的.NET工具(
BinaryFormatter
,XmlSerializer
,WCF,DataContractSerializer
) – 允许它直接作为远程引擎工作。 对于Jon的端口来说,这大概是一个相当大的分歧。
重新合并他们; 我认为我们都愿意接受它,但似乎不太可能同时需要这两个function集,因为它们针对的是不同的需求。