我想使用对象序列化在Mono服务器和Silverlight客户端之间通过网络进行通信。 序列化节省空间并且速度非常快非常重要,因为服务器将承载多个实时游戏。
我应该使用什么技术? BinaryFormatter为此应用程序中不需要的序列化类(版本,文化,类名,属性名等)增加了大量开销。
我可以做些什么来提高空间效率呢?
答案 0 :(得分:67)
您可以使用Protocol Buffers。我正在将所有序列化代码从BinaryFormatter更改为Protocol Buffers并获得非常好的结果。它在时间和空间上都更有效率。
Jon Skeet和Marc Gravell有两种.NET实现。
更新:可以找到正式的.NET实施here。
答案 1 :(得分:52)
我根据Northwind数据集提供了一些benchmarks for the leading .NET serializers。
@marcgravell二进制protobuf-net是基准测试的最快实现,比BCL中可用的Microsoft最快的序列化程序(XML DataContractSerializer)快 7x 。
我还维护了一些开源的高性能.NET文本序列化器:
答案 2 :(得分:28)
作为作者,我邀请您试试protobuf-net;它附带了Mono 2.0和Silverlight 2.0的二进制文件,并且是fast and efficient。如果您有任何问题,请给我发电子邮件(请参阅我的Stack Overflow个人资料);支持是免费的。
Jon的版本(参见之前接受的答案)也非常好,但是IMO protobuf-net版本更适合C# - 如果您正在将C#与Java谈论,那么Jon会是理想的,所以你可以使用类似的API两端。
答案 3 :(得分:8)
我有类似的问题,虽然我只是使用.NET。我希望尽可能快速,轻松地通过Internet发送数据。我找不到任何足够优化的东西,所以我制作了自己的序列化程序,名为NetSerializer。
NetSerializer有其局限性,但它们并不影响我的用例。我暂时没有做基准测试,但它比我发现的其他任何东西都要快得多。
我没有在Mono或Silverlight上尝试过。我敢打赌它适用于Mono,但我不确定Silverlight上DynamicMethods的支持程度。
答案 4 :(得分:5)
您可以尝试使用JSON。它不像协议缓冲区那样具有带宽效率,但使用Wireshark等工具监控消息要容易得多,这在调试问题时有很大帮助。 .NET 3.5附带了一个JSON序列化程序。
答案 5 :(得分:4)
您可以通过 DeflateStream 或 GZipStream 传递数据,以便在传输之前对其进行压缩。这些类存在于 System.IO.Compression 命名空间中。
答案 6 :(得分:3)
我有一个非常类似的问题 - 保存到文件。但是,以下内容也可以在网络中使用,因为它实际上是为远程处理而设计的。
解决方案是使用Simon Hewitt的图书馆 - 请参阅 Optimizing Serialization in .NET - part 2 。
该文章的Part 1指出(大胆是我的重点): “...如果你曾经使用.NET远程处理大量的 数据,你会发现有问题 可扩展性。对于少量数据,它运作良好 足够,但更大的数量需要大量的CPU和内存, 生成大量数据进行传输,以及 可能因Out Of Memory异常而失败。还有一个很大的 实际执行时间的问题 序列化 - 大量数据可能使其变得不可行 用于应用程序....“我的特定应用得到了类似的结果,40 节省时间更快,装载速度提高20倍(来自 几分钟到几秒钟)。序列化数据的大小是 也大大减少了。我不记得确切,但它 至少2-3次。
入门很容易。但是有一个
gotcha:只使用最高的.NET序列化
级别数据结构(以获得序列化/反序列化
开始)然后调用序列化/反序列化
直接用于最高级别的字段
数据结构。否则就不会有任何加速......
例如,如果是特定的数据结构(比如说
库不支持Generic.List
)
将使用序列化,这是禁忌。代替
在客户端代码(或类似)中序列化列表。举个例子
看到附近“'这是我们自己的编码。”在同一个功能
如下所列。
供参考:code from my application - 请参阅“注意:这是我们使用内置.NET的唯一地方......”。
答案 7 :(得分:2)
您可以尝试BOIS,它专注于打包数据大小,并提供目前为止最好的打包。 (我还没有看到更好的优化。)