协议缓冲区(Protocol Buffer)有多快或轻量级?

34

Protocol Buffer for .NET将比Remoting(SerializationFormat.Binary)更轻量级/更快吗? 是否有语言/框架方面的一流支持? 即,是否像处理Remoting/WebServices那样透明地处理它?

2个回答

37

我非常怀疑它将来会有直接的语言支持或甚至框架支持——这种东西使用第三方库完全没有问题。

我的Java代码移植版是明确的——你必须调用方法进行序列化/反序列化。(虽然有自动序列化/反序列化的RPC存根,但还没有RPC实现。)

Marc Gravell的项目与WCF非常匹配——据我所知,你只需要告诉它(一次)使用协议缓冲区进行序列化,其他部分都是透明的。

在速度方面,你应该查看Marc Gravell的基准测试页面。我的代码往往比他的略快,但两者都比框架中的其他序列化/反序列化选项要快得多。值得指出的是,协议缓冲区也更加受限制——它们不尝试对任意类型进行序列化,而只序列化受支持的类型。我们将来将尝试以可移植的方式(作为它们自己的协议缓冲区消息)支持更多的常见数据类型(decimal, DateTime等)。


37

一些性能和大小的指标在这个页面上。目前我没有Jon的统计数据,只是因为这个页面有点旧了(Jon:我们必须修复它!)。

关于透明度; protobuf-net可以通过合同连接到WCF;请注意,它也可以与基本http上的MTOM很好地配合使用。然而,这在Silverlight中不起作用,因为Silverlight缺少注入点。如果您使用svcutil,则还需要通过部分类添加属性到类(通过部分类)。

关于BinaryFormatter(远程调用); 是的,它完全支持;您可以通过一个简单的ISerializable实现来实现这一点(即只需使用相同的参数调用Serializer方法)。如果您使用protogen创建您的类,那么它也可以为您完成此操作:您可以通过参数在命令行上启用此选项(默认情况下未启用,因为BinaryFormatter不能在所有框架[CF等]上工作)。

请注意,对于非常小的对象(单个实例等)在本地远程调用(IPC)上,原始的BinaryFormatter性能实际上更好-但对于非平凡的图形或远程链接(网络远程调用),protobuf-net可以表现得更好。

我还应该指出,协议缓冲区的线路格式不直接支持继承;protobuf-net可以欺骗它(同时保留线路兼容性),但是像XmlSerializer一样,您需要预先声明子类。


为什么有两个版本?

开源的乐趣,我猜;-p Jon和我之前合作过,讨论过合并这两个版本的问题,但事实是它们针对两种不同的情况:

  • dotnet-protobufs (Jon的) 是现有Java版本的移植。这意味着对于任何已经使用Java版本的人来说,它具有非常熟悉的API,并且它是建立在典型的Java结构(构建器类、不可变数据类等)上的,但也加入了一些C#的特点。
  • protobuf-net (Marc的) 是一个从头开始重新实现的版本,遵循相同的二进制格式(确实,关键要求是您可以在不同格式之间交换数据),但使用典型的.NET语言习惯:
    • 可变数据类(没有构建器)
    • 序列化成员细节以属性的方式表达(与XmlSerializerDataContractSerializer等相似)

如果您正在处理Java和.NET客户端,则Jon的版本可能是一个好选择,因为它在两侧都具有熟悉的API。如果您只涉及.NET,则protobuf-net具有优势——熟悉的.NET样式API,但还具有以下优点:

  • 您不必强制使用契约优先(虽然您可以,并且提供了代码生成器)
  • 您可以重用现有的对象(实际上,[DataContract]和[XmlType]类通常可以毫无修改地使用)
  • 它完全支持继承(通过欺骗封装在线路上实现,这可能是协议缓冲区实现的独特之处?请注意,子类必须事先声明)
  • 它竭尽全力插入并利用核心.NET工具(BinaryFormatter、XmlSerializer、WCF、DataContractSerializer),使其直接作为远程引擎工作。这似乎会与Jon的端口的主要Java分支有很大的分歧。

关于合并它们; 我认为我们都会开放它,但是由于它们针对不同的需求,您似乎不太可能想要两个功能集。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接