protobuf-net 如何实现可观的性能?
我想了解为什么 针对 .NET 的协议缓冲区解决方案由 Marc Gravell 速度很快。
我可以理解最初的 Google 解决方案是如何实现其性能的:它预先生成了对象序列化的优化代码;我已经手工编写了一些序列化,并且知道如果避免反射,可以通过这种方式编写相当快的代码。但 Marc 的库是一个运行时解决方案,它使用属性并且不生成任何生成的代码。那么它是如何运作的呢?
I want to understand why the protocol buffers solution for .NET developed by Marc Gravell is as fast as it is.
I can understand how the original Google solution achieved its performance: it pre-generates optimized code for object serialization; I've written some serialization by hand and know that it is possible to write pretty fast code this way if you avoid reflection. But Marc's library is a runtime solution that uses attributes and doesn't produce any generated code. So how does it work ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
protobuf-net使用策略模式;根据需要(每种类型仅一次),它使用反射来查看类型,并构建一组序列化器(基于通用接口),可用于序列化和反序列化 - 所以在使用时它只是单步执行已知的序列化器集。
其中,它试图在与成员交谈时合理地利用反思;它使用
Delegate.CreateDelegate
与属性对话,并使用DynamicMethod
(和自定义 IL)与字段对话(如果可能的话;这取决于目标框架)。这意味着它始终与已知委托类型通信,而不仅仅是DynamicInvoke
(这非常慢)。不用发疯,代码确实在以下方面进行了一些优化(可以说以牺牲可读性为代价):
byte[]
缓冲(输入/输出流)事后看来,我认为我在泛型点上犯了一个错误;复杂性意味着强制仿制药进入系统将其从在一些地方塑造,并主动导致一些重大问题(对于复杂模型)紧凑框架。
我有一些设计(仅在我的脑海中)使用非通用接口来重构它,并改为(对于合适的框架)更多地使用
ILGenerator
(我的第一选择应该是Expression
,但这会强制使用更高的框架版本)。然而,问题是这需要相当长的时间才能开始工作,直到最近 我已经被淹没了。最近,我成功再次开始在 protobuf-net 上花费一些时间,所以希望我能清除积压的请求等并尽快开始处理。我还打算让它与反射之外的模型一起使用(即单独描述接线映射)。
我还应该澄清,如果您想使用生成的代码,有两个(可选)代码生成路径; protogen.exe,或 VS 加载项< /a>,允许从 .proto 文件生成代码。但这并不是需要 - 它主要在您有现有的 .proto 文件或打算与另一种语言(C++ 等)互操作以进行合约优先开发时有用。
protobuf-net uses a strategy pattern; as needed (once only per type) it uses reflection to look at the types, and builds a set of serializers (based on a common interface) that it can use to serialize and deserialize - so when in use it is just stepping through the known set of serializers.
Inside that, it tries to make sensible use of reflection when talking to members; it uses
Delegate.CreateDelegate
to talk to properties, andDynamicMethod
(and custom IL) to talk to fields (when possible; it depends on the target framework). This means that it is always talking to known delegate types, rather than justDynamicInvoke
(which is very slow).Without going mad, the code does have some optimisations (arguably at the expense of readability) in terms of:
byte[]
buffering (of the input/output streams)In hindsight, I think I made a mistake on the generics point; the complexity meant that forcing generics into the system bent it out of shape in a few places, and actively causes some major problems (for complex models) on compact framework.
I have some designs (in my head only) to refactor this using non-generic interfaces, and to instead (for suitable frameworks) make more use of
ILGenerator
(my first choice would have beenExpression
, but that forces a higher framework version). The problem, however, is that this is going to take a considerable amount of time to get working, and until very recently I've been pretty swamped.Recently I've managed to start spending some time on protobuf-net again, so hopefully I'll clear my backlog of requests etc and get started on that soon. It is also my intention to get it working with models other than reflection (i.e. describing the wire mapping separately).
I should also clarify that there are two (optional) codegen routes if you want to use generated code; protogen.exe, or the VS add-in, allow code generation from a .proto file. But this is not needed - it is useful mainly if you have an existing .proto file, or intent to interoperate with another language (C++ etc) for contract-first development.
其性能非常好!
你可以看到我做的包括protobuf在内的不同格式的综合比较——
http ://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/
此比较包括大小数据样本和不同格式。
我的帖子中的测试之一
Its performance very good!
You can see a comprehensive comparison between different formats including protobuf done by me-
http://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/
This comparison includes large and small data samples and different formats.
One of the tests in my post-