protobuf-net如何实现可观的性能?

时间:2009-11-12 13:13:59

标签: c# .net reflection protocol-buffers protobuf-net

我想了解the protocol buffers solution for .NETMarc Gravell开发的{{3}}为何如此快。

我可以理解原始Google解决方案如何实现其性能:它预先生成用于对象序列化的优化代码;我已经手工编写了一些序列化,并且知道如果避免反射,可以用这种方式编写相当快的代码。但Marc的库是一个运行时解决方案,它使用属性并且不会生成任何生成的代码。那么它是怎样工作的 ?

2 个答案:

答案 0 :(得分:44)

protobuf-net使用策略模式;根据需要(每种类型一次)它使用反射来查看类型,并构建一组序列化器(基于通用接口),它可用于序列化和反序列化 - 所以在使用时它只是逐步完成已知的序列化程序集。

里面,它试图在与会员交谈时合理地使用反思;它使用Delegate.CreateDelegate与属性进行通信,使用DynamicMethod(和自定义IL)与字段进行通信(如果可能,它取决于目标框架)。这意味着它始终与已知的委托类型进行对话,而不仅仅是DynamicInvoke(这非常慢)。

在没有发疯的情况下,代码确实有一些优化(可以说是以可读性为代价):

  • 本地byte[]缓冲(输入/输出流)
  • 使用固定大小的数组(而不是列表等);或许太多了
  • 使用泛型来避免装箱
  • 围绕二进制处理循环的大量调整/ twiddles / etc

事后来看,我认为我在仿制药方面犯了一个错误;复杂性意味着强制泛型进入系统bent it out of shape in a few places,并积极地导致一些主要问题(对于复杂模型)on compact framework

我有一些设计(仅在我的脑海中)使用 - 通用接口重构它,而是(对于合适的框架)更多地使用ILGenerator(我的首选)可能是Expression,但这会强制更高的框架版本)。然而,问题是这需要相当长的时间才能开始工作,直到最近I've been pretty swamped

最近我设法start spending some time on protobuf-net again,所以希望我能清除积压的请求等,并尽快开始。我还打算使用模型其他而不是反射(即分别描述导线映射)。


  

并且不生成任何生成的代码

我还应该澄清,如果你想使用生成的代码,有两个(可选的)codegen路由; protogen.exe或VS add-in允许从.proto文件生成代码。但这不是需要 - 它主要是有一个现有的.proto文件,或者意图与另一种语言(C ++等)互操作以进行契约优先开发。

答案 1 :(得分:-3)

它的表现非常好!

您可以看到不同格式之间的全面比较,包括由我完成的protobuf- http://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/

此比较包括大小数据样本和不同格式。

我的后期测试之一 enter image description here