如何加快C#的MongoDB反序列化
本文关键字:MongoDB 反序列化 何加快 | 更新日期: 2023-09-27 18:21:58
当从查询返回许多结果时,代码需要很长时间才能将数据转换为.net对象。这些都是基本对象,有一些字符串作为字段。我不确定,但我认为它使用反射来创建实例是很慢的。有办法加快速度吗?
10gen驱动程序不使用基于每个对象的反射。它使用每个类型一次反射来使用reflection.Emit生成序列化程序,因此第一个对象的序列化或反序列化可能很慢,但之后的任何对象都很快(相对而言)。
你的问题是,有没有办法加快速度?
如果你的对象很简单(不是嵌套文档、一些公共字段等),你可能没有什么可做的。你可以为类实现一个自定义序列化程序来提高一点性能,但我怀疑它是否会超过百分之几。
我还没有研究过它,Robert Stam(他也回答了这个问题)将是它的权威,但通过在驱动程序中并行化反序列化,在多核或多处理器系统上可能会获得一些性能。我还没有从这个角度来看驱动程序代码,所以这可能是Robert已经在追求的东西。
总的来说,我认为10秒内30000个对象对于任何不直接将对象存储为内存块的平台(比如SQL、Mongo、XML等)来说都是相当标准的(就像使用C++之类的语言一样)。
编辑:
看起来10gen驱动程序在返回光标供您枚举之前执行反序列化。因此,如果您的查询返回30000个结果,那么在驱动程序使游标可用于枚举之前,必须对所有30000个对象进行反序列化。我还没有看过jmongo驱动程序,但我预计它会起到相反的作用,并将反序列化推迟到在游标中枚举对象之后。
最终结果是,虽然两者可能花费相同的总时间来枚举和反序列化30000个对象,但jmongo驱动程序中的反序列化分布在整个枚举中,在c#驱动程序中,它是前置的。
差异是微妙的,但很可能解释你所看到的。
坏消息是"修复"是一个驱动程序的改变。你可以做的一件事是把你的查询分成块,一次查询10或100个对象。
不确定您是如何测量的。当C#驱动程序从服务器取回一批文档时,它会同时对它们进行反序列化,因此第一个文档可能会有延迟,但其他文档的速度非常快。真正重要的是每秒文档的总吞吐量,以及它是否足够快,足以使网络链路饱和,这是应该的
虽然许多标准.NET类都有硬编码的序列化程序,但POCO的序列化通常是通过类映射来处理的。反射用于构建类映射,但在进行序列化/反序列化时不再需要反射。
您可以通过为类编写自己手工编码的序列化程序(或使类实现IBsonSerializable)来稍微加快序列化/反序列化的速度,但由于瓶颈可能是网络,因此可能不值得这样做
以下是我正在使用的:
- 只读所需字段
- 缓存内存中经常需要但很少更改的对象
- 当我需要按规则读取许多对象时(例如,按过滤条件读取产品),我将所有产品存储在一个过滤对象中,并一次读取所有产品。缺点是在发生更改时重新计算此缓存