【问题标题】:Why is ProtoBuf-Net's performance so poor when serializing a list of strings?为什么 ProtoBuf-Net 在序列化字符串列表时性能如此差?
【发布时间】:2013-08-27 16:07:22
【问题描述】:

我正在使用 ProtoBuf,试图了解预期的压缩类型。作为一个测试用例,我有一个包含 10,000,000 个十个字符串的列表,我正在对其进行序列化,然后将其拆分为 3.9mb 的块。 ProtoBuf 似乎在这方面做得很糟糕,最终创建了 30 多个块。这是我运行的测试的结果。


ProtoBuf-Net 序列化:30 个 3.9mb 块

BinaryFormatter 序列化:12 个 3.9mb 块

带有 Deflate 流序列化的 BinaryFormatter:1 72kb 块


我这样调用 ProtoBuf:

ProtoBuf.Serializer.Serialize<List<string>>(names);

感谢任何帮助。

【问题讨论】:

  • 1000 万个 10 字符字符串占用 10E6*(4+10*2) = 229 MB = 59 个块。使用 8 位编码将其减少 2 倍非常简单。那个杯子是半满的。
  • @Hans protobuf 使用 UTF-8,所以我可以推断字符串基本上是 ASCII 范围 - 30 个块对于原始数据加上开销来说是正确的。当然可以优化(在我的回答中讨论)
  • elicid,下次用你的计算器,我们就不用了。 30*3.9MB/10000000=12 字节每 10 个字符的字符串。这个尺寸对我来说听起来很合理。

标签: c# .net serialization compression protobuf-net


【解决方案1】:

你能指出这里的测试数据是什么吗?我怀疑您正在多次序列化相同的字符串实例。 BinaryFormatter 总是重用引用。核心 protobuf 规范没有对象重用,因此 protobuf-net(为了兼容性)尊重这一点 - 但它确实 支持 对象重用(带有特殊的字符串以提高性能)。但它是严格选择加入的,以保持与其他 protobuf 实现的兼容性。

所以:如果数据真的要使用相同的字符串内容:我可以告诉你如何启用它。

如果数据真的会使用相同的字符串内容:那么你的测试是无效的。

【讨论】:

  • 马克,这正是我需要知道的。感谢您让我深入了解 ProtoBuf 如何在幕后工作。不过,我将如何按照您的建议进行优化?现在我只是好奇。
  • @elucid8 我需要检查,但我认为可以这样做 - 如果没有,它可能需要一个单独的类:public class SomeWrapper { [ProtoMember(1, AsReference=true, DataFormat=DataFormat.Group)] public List&lt;string&gt; Items {get;set;} }
猜你喜欢
  • 2015-09-10
  • 1970-01-01
  • 2023-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 2021-01-14
  • 1970-01-01
相关资源
最近更新 更多