34

.NET 的协议缓冲区会比 Remoting(SerializationFormat.Binary)更轻量/更快吗?在语言/框架方面会有一流的支持吗?即它是否像 Remoting/WebServices 一样透明地处理?

4

2 回答 2

37

我非常怀疑它是否会获得直接的语言支持甚至框架支持——这种东西在 3rd 方库中处理得非常好。

我自己的 Java 代码端口是显式的 - 您必须调用方法来序列化/反序列化。(有 RPC 存根会自动序列化/反序列化,但还没有 RPC 实现。)

不过, Marc Gravell 的项目非常适合 WCF - 据我所知,您只需告诉它(一次)使用协议缓冲区进行序列化,其余的都是透明的。

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

于 2009-01-24T10:10:13.830 回答
37

此页面上有一些性能和大小指标。我现在还没有 Jon 的统计数据,只是因为页面有点旧(Jon:我们必须解决这个问题!)。

重新透明;protobuf-net可以通过合约挂钩到 WCF;请注意,它也可以与 MTOM 通过 basic-http 很好地配合使用。但是,这不适用于 Silverlight,因为 Silverlight 缺少注入点。如果使用 svcutil,还需要向类添加属性(通过部分类)。

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

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

我还应该注意,协议缓冲区有线格式不直接支持继承;protobuf-net 可以欺骗这一点(同时保持线路兼容性),但与 XmlSerializer 一样,您需要预先声明子类。


为什么有两个版本?

开源的乐趣,我猜 ;-p Jon 和我之前曾参与过联合项目,并讨论过合并这两个项目,但事实是它们针对两个不同的场景:

  • dotnet-protobufs (Jon's) 是现有 java 版本的一个端口。这意味着对于已经使用 java 版本的任何人来说,它都有一个非常熟悉的 API,并且它建立在典型的 java 构造(构建器类、不可变数据类等)之上——带有一些 C# 曲折。
  • protobuf-net (Marc's) 是一个全新的重新实现,遵循相同的二进制格式(实际上,一个关键要求是您可以在不同格式之间交换数据),但使用典型的 .NET 习惯用法:
    • 可变数据类(无构建器)
    • 序列化成员细节以属性表示(类似于XmlSerializer,DataContractSerializer等)

如果您正在处理 java 和 .NET 客户端,Jon's 可能是双方熟悉的 API 的不错选择。如果你是纯 .NET,protobuf-net 有优势——熟悉的 .NET 风格的 API,还有:

  • 您不必被迫以合同为先(尽管您可以,并且提供了代码生成器)
  • 您可以重新使用现有的对象(事实上,[DataContract][XmlType]通常可以在没有任何更改的情况下使用)
  • 它完全支持继承(它通过欺骗封装在网络上实现)(对于协议缓冲区实现可能是唯一的?请注意,必须提前声明子类)
  • 它不遗余力地插入和利用核心 .NET 工具(BinaryFormatter、、XmlSerializerWCF、DataContractSerializer)——允许它直接作为远程处理引擎工作。这可能与 Jon 的端口的主要 Java 主干有很大的区别。

重新合并它们;我认为我们都会对此持开放态度,但您似乎不太可能同时需要这两个功能集,因为它们针对的是不同的需求。

于 2009-01-24T11:42:53.270 回答