我想明白为什么.NET 的协议缓冲区解决方案 http://code.google.com/p/protobuf-net/由开发马克·格拉维尔 https://stackoverflow.com/users/23354/marc-gravell就这么快。
我可以理解最初的 Google 解决方案是如何实现其性能的:它预先生成了对象序列化的优化代码;我已经手工编写了一些序列化,并且知道如果避免反射,可以通过这种方式编写相当快的代码。但 Marc 的库是一个运行时解决方案,它使用属性并且不生成任何生成的代码。那么它是怎样工作的 ?
protobuf-net使用策略模式;根据需要(每种类型仅一次),它使用反射来查看类型,并构建一组可用于序列化和反序列化的序列化器(基于通用接口) - 所以使用时它只是单步执行已知的一组序列化器。
Inside它试图在与成员交谈时合理地利用反思;它用Delegate.CreateDelegate
与物业交谈,以及DynamicMethod
(和自定义 IL)与字段对话(如果可能;这取决于目标框架)。这意味着它总是在与known委托类型,而不仅仅是DynamicInvoke
(这非常慢)。
不用发疯,代码确实在以下方面进行了一些优化(可以说是以牺牲可读性为代价):
- local
byte[]
(输入/输出流的)缓冲
- 使用固定大小的数组(而不是列表等);也许太多了
- 使用泛型来避免装箱
- 围绕二进制处理循环进行大量调整/旋转等
事后看来,我认为我在泛型问题上犯了一个错误;复杂性意味着强制仿制药进入系统有几个地方变形了 http://marcgravell.blogspot.com/2009/05/generics-and-when-not-to.html,并主动引发一些重大问题(对于复杂模型)在紧凑的框架上 http://marcgravell.blogspot.com/2009/03/compact-framework-woes-revisted.html.
我有一些设计(仅在我的脑海中)来重构它non-通用接口,并且(对于合适的框架)更多地使用ILGenerator
(我的第一选择是Expression
,但这会强制使用更高的框架版本)。然而,问题是这需要相当长的时间才能开始工作,直到最近我已经被淹没了 http://twitter.com/marcgravell/status/5584270993.
最近我设法再次开始花一些时间在 protobuf-net 上 http://marcgravell.blogspot.com/2009/03/compact-framework-woes-revisted.html,所以希望我能清除积压的请求等,并尽快开始处理。我的目的也是让它与模型一起工作other比反射(即单独描述线路映射)。
并且不产生任何生成的代码
我还应该澄清,如果您想使用生成的代码,有两个(可选)代码生成路径; protogen.exe,或VS 插件 http://marcgravell.blogspot.com/2009/07/protobuf-net-now-with-added-orcas.html,允许从 .proto 文件生成代码。但这不是needed- 主要如果您有现有的 .proto 文件,或者打算与另一种语言(C++ 等)进行互操作以进行合约优先开发,那么它很有用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)