如何为C#加速MongoDB反序列化

时间:2012-01-28 21:41:25

标签: c# asp.net mongodb reflection

从查询返回许多结果时,代码需要很长时间才能将数据转换为.net对象。这些是基本对象,有几个字符串作为字段。我不确定,但我认为它使用反射来创建缓慢的实例。有办法加快速度吗?

3 个答案:

答案 0 :(得分:2)

不确定您的测量方式。当C#驱动程序从服务器返回一批文档时,它会立即对它们进行反序列化,因此第一个文档可能存在延迟,但其余文档的速度非常快。真正重要的是每秒文档的总吞吐量以及它是否足够快以使网络链接饱和,应该是这样。

虽然许多标准.NET类都有硬编码序列化器,但POCO的序列化通常通过类映射来处理。反射用于构建类映射,但在进行序列化/反序列化时不再需要反射。

您可以通过为您的类编写自己的手动编码序列化器(或通过使您的类实现IBsonSerializable)来加快序列化/反序列化,但是因为瓶颈可能是网络,所以它可能不值得。 / p>

答案 1 :(得分:2)

10gen驱动程序不会在每个对象的基础上使用反射。它使用每种类型的反射一次使用Reflection.Emit生成一个序列化器,因此第一个对象的序列化或反序列化可能很慢,但之后的任何对象都很快(相对)。

你的问题 - 有什么方法可以加快速度吗?

如果你的对象很简单(不是嵌套文档,一些公共字段等),你可能做的事情可能不多。您可以为该类实现一个自定义序列化程序以提高性能,但我怀疑它会超过百分之几。

我没有调查过,而Robert Stam(也回答了这个问题)将是它的权威,但是通过在驱动程序中并行化反序列化,可能会在多核或多处理器系统上获得一些性能。我还没有从那个角度看过驱动程序代码,所以它可能是罗伯特已经追求的东西。

总的来说,我认为10秒内30,000个对象几乎适用于任何平台 - SQL,Mongo,XML等,它们不直接将对象存储为内存blob(就像你可以使用像C ++这样的语言) )。

编辑:

看起来10gen驱动程序在返回光标以进行枚举之前执行反序列化。因此,如果您的查询返回30,000个结果,则在驱动程序使游标可用于枚举之前,必须对所有30,000个对象进行反序列化。我没有看过jmongo驱动程序,但我希望它反过来,并推迟反序列化直到在游标中枚举一个对象之后。

最终结果是,虽然两者可能花费相同的总时间来枚举和反序列化30,000个对象,但jmongo驱动程序中的反序列化遍布整个枚举,其中在c#驱动程序中它是前载的。

差异很微妙,但很可能解释你所看到的。

坏消息是“修复”是司机改变。您可以做的一件事是以块的形式断开查询,一次查询10个或100个对象。

答案 2 :(得分:0)

以下是我正在使用的内容:

  1. 只读必填字段
  2. 缓存通常需要但很少在内存中更改的对象
  3. 当我需要按规则读取多个对象时(例如按过滤条件的产品),我将所有产品存储在单个过滤器对象中,并立即读取所有这些对象。当更改内容时,缺点会重新计算此缓存。