.NET中快速而紧凑的对象序列化
我想使用对象序列化在Mono服务器和Silverlight客户端之间通过networking进行通信。 因为服务器将要托pipe多个实时游戏,所以序列化非常节省空间并且相当快。
我应该使用什么技术? BinaryFormatter为序列化的类(版本,文化,类名称,属性名称等)添加了大量的开销,这在此应用程序中是不需要的。
我能做些什么来提高这个空间的效率?
您可以使用协议缓冲区 。 我将所有的序列化代码从BinaryFormatter压缩到Protocol Buffers,并获得非常好的结果。 它在时间和空间上都更加高效。
Jon Skeet和Marc Gravell有两个.NET实现。
我有一些基于Northwind数据集的.NET序列化器的基准testing 。
@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的支持级别。
您可以通过DeflateStream或GZipStream传递数据在传输之前进行压缩。 这些类位于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,它专注于打包的数据大小,并提供迄今为止最好的包装。 (我还没有看到更好的优化呢。)
- C#中的错误运算符是什么?
- 通常最好使用 – StringComparison.OrdinalIgnoreCase或StringComparison.InvariantCultureIgnoreCase?
- 如何在C#中使用TransactionScope?
- 如何跳出C#中的foreach循环?
- 符号文件不加载在Visual Studio 2012中debugging自定义项目
- 你如何防止窗户被移动?
- 如何获取各种MessageBoxImage或MessageBoxIcon(s)的图像?
- 在C#中使用WebClient有一种方法来redirect后获取网站的url?
- HttpContent.ReadAsAsync在哪里?