我正在编写计算成本高昂的应用程序(NLP机器学习任务),需要进行优化。
由于我的代码有很多for循环,我使用Parallel.For
(和变体)来并行化最外层的循环。
我还使用了数组和Dictionary
来构建一些可以大大降低成本的指数。
VS2010的分析器表明应用程序花费大部分时间在Dictionary.TryGetValue()
(这是索引的副产品)。
这引出了一个问题,我是否可以做得更好?怎么样?
我的第一个问题是,是否普遍认为ConcurrentDictionary.TryGetValue
表现得更好
Dictionary.TryGetValue
在我的场景中 - 很多读者,没有作家?
我没有动力编写自己的hashmap,因为它可能比.NET的集合更糟糕。但是,是否有任何库可以保证更快地查找我的场景?
也许哈希码实现会降低速度?
答案 0 :(得分:9)
Dictionary.TryGetValue已经得到了很好的优化:
此方法接近O(1)操作。
您还没有提到字典的键是什么,如果您使用自定义类型,请确保您已正确实现其GetHashCode方法,因为字典和哈希表依赖它并广泛使用它
答案 1 :(得分:4)
我的第一个问题是,是否普遍认为
ConcurrentDictionary.TryGetValue
在我的情景中表现优于Dictionary.TryGetValue
- 许多读者,没有作家?
我还没有对它进行过测试,但我通常期望并发实现会产生额外的开销,整体上只是较慢。当您需要同步访问时 - 即如果您的以读取为中心的代码需要lock
字典,那么并发版本(没有锁定)可能会更快。既然你提到你的代码没有编写器,我猜你没有使用lock
,因此没有任何理由去看另一个实现。也就是说,它可能值得分析它,但即使它 更快(并且再次:我希望它稍微更慢),我只希望它稍微更快 - 因此不太可能显着改变性能。
答案 2 :(得分:0)
当查看声称方法对大部分执行时间负责的分析器结果时,同样重要的是要弄清楚它是否是因为:
如果TryGetValue占大部分时间因为它被调用了太多次,则可能表明您需要降低索引/查找算法的复杂度,以便TryGetValue可以不经常打电话。
如果需要很长时间每次调用,那么进一步调查TryGetValue
方法是值得的。但是,正如Pavel所说,TryGetValue
本身已经得到了很好的优化。很可能由TryGetValue
调用的方法(可被你覆盖的方法)被指责。通常,您需要注意GetHashCode
和Equals
方法。调用TryGetValue
时将调用它们。 Equals
可能会被多次调用。我的经验是Equals
方法通常有更好的机会成为问题,因为某些框架构造的内置相等比较涉及反射。