我想了解the protocol buffers solution for .NET为Marc Gravell开发的{{3}}为何如此快。
我可以理解原始Google解决方案如何实现其性能:它预先生成用于对象序列化的优化代码;我已经手工编写了一些序列化,并且知道如果避免反射,可以用这种方式编写相当快的代码。但Marc的库是一个运行时解决方案,它使用属性并且不会生成任何生成的代码。那么它是怎样工作的 ?
答案 0 :(得分:44)
protobuf-net使用策略模式;根据需要(每种类型一次)它使用反射来查看类型,并构建一组序列化器(基于通用接口),它可用于序列化和反序列化 - 所以在使用时它只是逐步完成已知的序列化程序集。
在里面,它试图在与会员交谈时合理地使用反思;它使用Delegate.CreateDelegate
与属性进行通信,使用DynamicMethod
(和自定义IL)与字段进行通信(如果可能,它取决于目标框架)。这意味着它始终与已知的委托类型进行对话,而不仅仅是DynamicInvoke
(这非常慢)。
在没有发疯的情况下,代码确实有一些优化(可以说是以可读性为代价):
byte[]
缓冲(输入/输出流)事后来看,我认为我在仿制药方面犯了一个错误;复杂性意味着强制泛型进入系统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/
此比较包括大小数据样本和不同格式。
我的后期测试之一