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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/549128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:45:53  来源:igfitidea点击:

Fast and compact object serialization in .NET

c#.netserialization

提问by Dennis Kempin

I want to use object serialization to communicate over the network between a Monoserver and Silverlight clients. It is pretty important that serialization is space efficient and pretty fast, as the server is going to host multiple real time games.

我想使用对象序列化在Mono服务器和 Silverlight 客户端之间通过网络进行通信。序列化的空间效率和速度非常重要,因为服务器将托管多个实时游戏。

What technique should I use? The BinaryFormatter adds a lot of overhead to serialized classes (Version, culture, class name, property names, etc.) that is not required within this application.

我应该使用什么技术?BinaryFormatter 向序列化类(版本、区域性、类名、属性名等)增加了很多开销,这些开销在此应用程序中是不需要的。

What can I do to make this more space efficient?

我该怎么做才能提高空间效率?

采纳答案by Jorge Villuendas Zapatero

You can use Protocol Buffers. I'm changing all my serialization code from BinaryFormatter with compression to Protocol Buffers and obtaining very good results. It's more efficient in both time and space.

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

There are two .NET implementations by Jon Skeetand Marc Gravell.

Jon SkeetMarc Gravell有两个 .NET 实现。

Update: Official .NET implementation can be found here.

更新:可以在此处找到官方 .NET 实现。

回答by Sean

You could pass the data through a DeflateStreamor GZipStreamto compress it prior to transmission. These classes live in the System.IO.Compressionnamespace.

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

回答by Pablote

You could try using JSON. It's not as bandwidth efficient as Protocol Buffers, but it would be a lot easier to monitor messages with tools like Wireshark, which helps a lot when debugging problems. .NET 3.5 comes with a JSON serializer.

您可以尝试使用 JSON。它的带宽效率不如 Protocol Buffers,但使用 Wireshark 等工具监控消息会容易得多,这在调试问题时很有帮助。.NET 3.5 带有一个 JSON 序列化程序。

回答by Marc Gravell

As the author, I would invite you to try protobuf-net; it ships with binaries for both Mono2.0 and Silverlight2.0, and is fast and efficient. If you have any problems whatsoever, just drop me an e-mail (see my Stack Overflow profile); support is free.

作为作者,我会邀请您尝试protobuf-net;它附带了Mono2.0 和Silverlight2.0 的二进制文件,并且快速高效。如果您有任何问题,请给我发电子邮件(请参阅我的 Stack Overflow 个人资料);支持是免费的。

Jon's version (see the earlier accepted answer) is also very good, but IMO the protobuf-net version is more idiomatic for C# - Jon's would be ideal if you were talking C# to Java, so you could have a similar API at both ends.

Jon 的版本(请参阅先前接受的答案)也非常好,但 IMO protobuf-net 版本更适合 C# - 如果您将 C# 与 Java 交谈,Jon 的版本将是理想的选择,因此您可以在两端使用类似的 API。

回答by Peter Mortensen

I had a very similar problem - saving to a file. But the following can also be used over a network as it was actually designed for remoting.

我有一个非常相似的问题 - 保存到文件。但是以下内容也可以通过网络使用,因为它实际上是为远程处理而设计的。

The solution is to use Simon Hewitt's library - see Optimizing Serialization in .NET - part 2.

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

Part 1of the article states (the bold is my emphasis): "... If you've ever used .NET remoting for large amounts of data, you will have found that there are problems with scalability. For small amounts of data, it works well enough, but larger amounts take a lot of CPU and memory, generate massive amounts of data for transmission, and can fail with Out Of Memory exceptions. There is also a big problem with the time taken to actually perform the serialization - large amounts of data can make it unfeasible for use in apps ...."

文章的第 1 部分指出(粗体是我的重点):“...如果您曾经使用 .NET 远程处理大量数据,您会发现可扩展性存在问题。对于少量数据,它工作得很好,但大量占用大量 CPU 和内存, 生成大量数据进行传输,并且可能因内存不足异常而失败。实际执行序列化所花费的时间也有一个大问题 - 大大量数据可能使其无法在应用程序中使用......”

I got a similar result for my particular application, 40 times faster saving and 20 times faster loading (from minutes to seconds). The size of the serialised data was also much reduced. I don't remember exactly, but it was at least 2-3 times.

对于我的特定应用程序,我得到了类似的结果,保存速度提高了 40 倍,加载速度提高了 20 倍(从几分钟到几秒)。序列化数据的大小也大大减少。具体不记得了,至少有2-3次。

It is quite easy to get started. However there is one gotcha: only use .NET serialisation for the very highest level datastructure (to get serialisation/deserialisation started) and then call the serialisation/deserialisation functions directly for the fields in the highest level datastructure. Otherwise there will not be any speed-up... For instance, if a particular data structure (say Generic.List) is not supported by the library then .NET serialisation will used instead and this is a no-no. Instead serialise the list in client code (or similar). For an example see near "'This is our own encoding." in the same function as listed below.

很容易上手。然而,有一个问题:仅对最高级别的数据结构使用 .NET 序列化(以启动序列化/反序列化),然后直接为最高级别数据结构中的字段调用序列化/反序列化函数。否则不会有任何加速......例如,如果Generic.List库不支持特定的数据结构(比如 ),那么将使用 .NET 序列化,这是一个禁忌。而是在客户端代码(或类似代码)中序列化列表。有关示例,请参见“'这是我们自己的编码”。在与下面列出的相同的功能中。

For reference: code from my application- see near "Note: this is the only place where we use the built-in .NET ...".

供参考:来自我的应用程序的代码- 请参阅“注意:这是我们使用内置 .NET 的唯一地方......”。

回答by mythz

I have some benchmarks for the leading .NET serializersavailable based on the Northwind dataset.

我有一些基于 Northwind 数据集的领先 .NET 序列化程序的基准测试

Northwind .NET serialization benchmarks

Northwind .NET 序列化基准测试

@marcgravell binary protobuf-net is the fastest implementations benchmarked that is about 7xfaster than Microsoft fastest serializer available (the XML DataContractSerializer) in the BCL.

@marcgravell 二进制 protobuf-net 是经过基准测试的最快实现,比 BCL 中可用的 Microsoft 最快序列化器(XML DataContractSerializer)快约7 倍

I also maintain some open-source high-performance .NET text serializers as well:

我还维护了一些开源的高性能 .NET 文本序列化程序:

回答by Tomba

I had a similar problem, although I'm just using .NET. I wanted to send data over the Internet as quickly and easily as possible. I didn't find anything that would be optimized enough, so I made my own serializer, named NetSerializer.

我有一个类似的问题,虽然我只是使用 .NET。我想尽可能快速、轻松地通过 Internet 发送数据。我没有找到任何足够优化的东西,所以我制作了自己的序列化器,命名为NetSerializer

NetSerializer has its limitations, but they didn't affect my use case. And I haven't done benchmarks for a while, but it was much much faster than anything else I found.

NetSerializer 有其局限性,但它们不会影响我的用例。我已经有一段时间没有做基准测试了,但它比我发现的任何其他东西都要快得多。

I haven't tried it on Mono or Silverlight. I'd bet it works on Mono, but I'm not sure what the level of support is for DynamicMethods on Silverlight.

我还没有在 Mono 或 Silverlight 上尝试过。我敢打赌它适用于 Mono,但我不确定 Silverlight 上对 DynamicMethods 的支持级别。

回答by Salar

You can try BOIS which focuses on packed data size and provides the best packing so far. (I haven't seen better optimization yet.)

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

https://github.com/salarcode/Bois

https://github.com/salarcode/Bois