.NET中快速而紧凑的对象序列化

我想使用对象序列化在Mono服务器和Silverlight客户端之间通过networking进行通信。 因为服务器将要托pipe多个实时游戏,所以序列化非常节省空间并且相当快。

我应该使用什么技术? BinaryFormatter为序列化的类(版本,文化,类名称,属性名称等)添加了大量的开销,这在此应用程序中是不需要的。

我能做些什么来提高这个空间的效率?

您可以使用协议缓冲区 。 我将所有的序列化代码从BinaryFormatter压缩到Protocol Buffers,并获得非常好的结果。 它在时间和空间上都更加高效。

Jon Skeet和Marc Gravell有两个.NET实现。

我有一些基于Northwind数据集的.NET序列化器的基准testing 。

Northwind .NET序列化基准

@marcgravell binary protobuf-net是基准testing中速度最快的实现方式,比BCL中Microsoft最快的可用序列化程序(XML DataContractSerializer)快7倍

我也维护一些开源高性能的.NET文本串行器:

  • JSV TypeSerializer紧凑,干净,类似JSON + CSV的格式,比DataContractSerializer快3.1倍
  • 以及2.6倍的JsonSerializer。

作为作者,我会邀请您尝试protobuf网 ; 它为Mono 2.0和Silverlight 2.0提供了二进制文件,并且快速高效 。 如果你有任何问题,只要给我发一封电子邮件(见我的堆栈溢出configuration文件); 支持是免费的。

Jon的版本(见前面接受的答案)也是非常好的,但是IMO的protobuf-net版本对于C#来说更加惯用 – 如果你正在谈论C#到Java,Jon会是理想的,所以你可以在两端都有类似的API。

我有一个类似的问题,虽然我只是使用.NET。 我想通过互联网尽可能快捷地发送数据。 我没有find足够优化的东西,所以我制作了自己的序列化程序,名为NetSerializer 。

NetSerializer有其局限性,但它们并不影响我的使用情况。 一段时间以来,我还没有做过基准testing,但是比我发现的要快得多。

我还没有尝试过单声道或Silverlight。 我敢打赌它在Mono上工作,但我不确定Silverlight上DynamicMethods的支持级别。

您可以通过DeflateStreamGZipStream传递数据在传输之前进行压缩。 这些类位于System.IO.Compression命名空间中。

你可以尝试使用JSON。 它不像Protocol Buffers那样具有带宽效率,但是使用Wireshark这样的工具来监视消息要容易得多,这在debugging问题时帮助很大。 .NET 3.5带有一个JSON序列化器。

我有一个非常类似的问题 – 保存到一个文件。 但是,以下内容也可以在networking上使用,因为它实际上是为远程处理而devise的。

解决scheme是使用Simon Hewitt的库 – 请参阅.NET中的优化序列化 – 第2部分

本文的第1部分指出(大胆是我的重点):“…如果你曾经使用.NET远程处理大量数据,你会发现有可伸缩性的问题,对于less量的数据,它工作的很好,但是大量的CPU和内存占用很多, 产生大量的数据用于传输 ,并且可能会因为Out Of Memoryexception而失败,实际执行序列化所花费的时间也很大 – 大大量的数据可能使它不适用于应用程序….“

对于我的特定应用程序,我得到了类似的结果,节省了40倍,加载速度快了20倍(从几分钟到几秒)。 序列化数据的大小也大大减less了。 我不记得确切,但至less有2-3次。

开始很容易。 但是有一个问题:只能使用.NET序列化来实现最高级别的数据结构(开始序列化/反序列化),然后直接调用序列化/反序列化函数来处理最高级别数据结构中的字段。 否则就不会有任何加速…例如,如果某个特定的数据结构(如Generic.List )不被该库支持,那么将使用.NET序列化,而不是这样。 而是在客户端代码(或类似的)中序列化列表。 例如,请参阅“”这是我们自己的编码“。 与下面列出的function相同。

参考: 从我的应用程序代码 – 请参阅附近“注意:这是唯一的地方,我们使用内置的.NET …”。

您可以尝试BOIS,它专注于打包的数据大小,并提供迄今为止最好的包装。 (我还没有看到更好的优化呢。)

https://github.com/salarcode/Bois