C# 优化Dictionary.TryGetValue()
我正在编写一个计算代价高昂的应用程序(NLP机器学习任务),它需要优化 因为我的代码有很多for循环,所以我使用了C# 优化Dictionary.TryGetValue(),c#,multithreading,.net-4.0,C#,Multithreading,.net 4.0,我正在编写一个计算代价高昂的应用程序(NLP机器学习任务),它需要优化 因为我的代码有很多for循环,所以我使用了Parallel.for(和变体)来并行化最外层的循环。 我还使用数组和字典s构建了一些索引,大大降低了成本 VS2010的profiler指出,应用程序的大部分时间都花在Dictionary.TryGetValue()(这是索引的副产品)上 这就引出了一个问题:我是否能做得更好?怎么做 我的第一个问题是,ConcurrentDictionary.TryGetValue的性能是否比
Parallel.for
(和变体)来并行化最外层的循环。
我还使用数组和字典
s构建了一些索引,大大降低了成本
VS2010的profiler指出,应用程序的大部分时间都花在Dictionary.TryGetValue()
(这是索引的副产品)上
这就引出了一个问题:我是否能做得更好?怎么做
我的第一个问题是,ConcurrentDictionary.TryGetValue
的性能是否比
Dictionary.TryGetValue
在我的场景中——很多读者,没有作者
我没有动力编写自己的hashmap,因为它可能比.NET的集合更糟糕。但是是否有任何库可以保证更快地查找我的场景
也许hashcode的实现正在放慢速度?根据MSDN的说法,已经进行了很好的优化:
此方法接近O(1)操作
您没有提到字典的键是什么,如果您使用自定义类型,请确保正确实现了它的方法,因为字典和哈希表依赖它并广泛使用它
我的第一个问题是,在我的场景中,ConcurrentDictionary.TryGetValue
的性能是否比Dictionary.TryGetValue
好——很多读者,没有作者
我还没有测试过它,但我通常希望并发实现会有额外的开销,总体上会稍微慢一些。当您需要同步访问时,就会出现这种差异——即,如果以读取为中心的代码需要
锁定
字典,那么并发版本(不带锁定)可能会更快。既然您提到您的代码没有编写器,我猜您没有使用lock
s,因此没有任何理由将一个实现置于另一个实现之上。这就是说,分析它可能是值得的,但即使它更快(我也希望它稍微慢一点),我也只希望它稍微快一点——所以不太可能显著改变性能。当查看分析程序结果时,该结果声称一个方法对大部分执行时间负责,同样重要的是要弄清楚这是否是因为:
只有在每次调用
TryGetValue
需要很长时间的情况下,才有必要进一步研究TryGetValue
方法。然而,正如Pavel提到的,TryGetValue
本身已经得到了很好的优化。很可能是由于TryGetValue
调用的方法,也就是您可以重写的方法,导致了错误。通常需要注意GetHashCode
和Equals
方法。调用TryGetValue
时,将调用这两个函数Equals
可以多次调用。我的经验是,Equals
方法通常更有可能成为问题,因为某些框架构造的内置相等比较涉及反射 O(1)
与“优化得很好”不是一回事。我可以在方法的开头添加Thread.Sleep(60000)
,但仍然可以合法地声明它是O(1)
;pYes,您可以,但如果您追求最高性能,则不会;)我的意思是,TryGetValue方法不太可能导致速度减慢,但如果编码不正确,GetHashCode方法可能会导致速度减慢。我已经分析了GetHashCode方法,程序在其中花费的时间不到0,1%。我想我需要用另一种方式来解决这个瓶颈。