优化Dictionary.TryGetValue()

时间:2013-05-16 06:59:08

标签: c# multithreading .net-4.0

我正在编写计算成本高昂的应用程序(NLP机器学习任务),需要进行优化。

由于我的代码有很多for循环,我使用Parallel.For(和变体)来并行化最外层的循环。 我还使用了数组和Dictionary来构建一些可以大大降低成本的指数。

VS2010的分析器表明应用程序花费大部分时间在Dictionary.TryGetValue()(这是索引的副产品)。

这引出了一个问题,我是否可以做得更好?怎么样?

我的第一个问题是,是否普遍认为ConcurrentDictionary.TryGetValue表现得更好 Dictionary.TryGetValue在我的场景中 - 很多读者,没有作家?

我没有动力编写自己的hashmap,因为它可能比.NET的集合更糟糕。但是,是否有任何库可以保证更快地查找我的场景?

也许哈希码实现会降低速度?

3 个答案:

答案 0 :(得分:9)

根据MSDN,

Dictionary.TryGetValue已经得到了很好的优化:

  

此方法接近O(1)操作。

您还没有提到字典的键是什么,如果您使用自定义类型,请确保您已正确实现其GetHashCode方法,因为字典和哈希表依赖它并广泛使用它

答案 1 :(得分:4)

  

我的第一个问题是,是否普遍认为ConcurrentDictionary.TryGetValue在我的情景中表现优于Dictionary.TryGetValue - 许多读者,没有作家?

我还没有对它进行过测试,但我通常期望并发实现会产生额外的开销,整体上只是较慢。当您需要同步访问时 - 即如果您的以读取为中心的代码需要lock字典,那么并发版本(没有锁定)可能会更快。既然你提到你的代码没有编写器,我猜你没有使用lock,因此没有任何理由去看另一个实现。也就是说,它可能值得分析它,但即使它 更快(并且再次:我希望它稍微更慢),我只希望它稍微更快 - 因此不太可能显着改变性能。

答案 2 :(得分:0)

当查看声称方法对大部分执行时间负责的分析器结果时,同样重要的是要弄清楚它是否是因为:

  1. 该方法被调用了太多次,或
  2. 单次调用该方法需要很长时间
  3. 如果TryGetValue占大部分时间因为它被调用了太多次,则可能表明您需要降低索引/查找算法的复杂度,以便TryGetValue可以不经常打电话。

    如果需要很长时间每次调用,那么进一步调查TryGetValue方法是值得的。但是,正如Pavel所说,TryGetValue 本身已经得到了很好的优化。很可能由TryGetValue调用的方法(可被你覆盖的方法)被指责。通常,您需要注意GetHashCodeEquals方法。调用TryGetValue时将调用它们。 Equals可能会被多次调用。我的经验是Equals方法通常有更好的机会成为问题,因为某些框架构造的内置相等比较涉及反射。