【发布时间】:2010-08-09 05:31:07
【问题描述】:
我正在 O(n^2) 循环中进行Dictionary<> 查找,并且需要它快得离谱。它不是。有人对Dictionary<> 的实现方式有任何见解吗?在通过分析器运行我的代码并确定字典查找是 CPU 时间的大部分之后,我正在使用一个隔离的测试用例测试字典性能。我的测试代码是这样的:
Int32[] keys = new Int32[10] { 38784, 19294, 109574, 2450985, 5, 398, 98405, 12093, 909802, 38294394 };
Dictionary<Int32, MyData> map = new Dictionary<Int32, MyData>();
//Add a bunch of things to map
timer.Start();
Object item;
for (int i = 0; i < 1000000; i++)
{
for (int j = 0; j < keys.Length; j++)
{
bool isFound = map.ContainsKey(keys[j]);
if (isFound)
{
item = map[keys[j]];
}
}
}
timer.Stop();
ContainsKey 和 map[] 是两个慢的部分(同样慢)。如果我添加一个 TryGetValue,它的速度几乎与 ContainsKey 相同。这里有一些有趣的事实..
Dictionary<Guid, T> 的速度大约是 Dictionary<Int32, T> 的两倍。 Dictionary<String, T> 的速度大约是 Guid 字典的两倍。 Dictionary<Byte, T> 比使用 Ints 快 50%。这让我相信 Dictionary 正在执行 O(log n) 二进制搜索来查找键,而键上的比较运算符是瓶颈。出于某种原因,我不认为它是作为 Hashtable 实现的,因为 .NET 已经有一个 Hashtable 类,而且根据我的经验,它甚至比 Dictionary 还要慢。
我正在构建的字典一次只能由一个线程访问,因此读取锁定不是问题。 RAM 也不是问题。字典很可能只有大约 10 个桶,但每个桶可以指向大约 2,000 个可能的事物之一。有人对如何加快速度有任何反馈吗?谢谢!
迈克
【问题讨论】:
-
"如果我添加 TryGetValue,它的速度几乎与 ContainsKey 相同。" TryGetValue 与 ContainsKey 的速度相同,但同时返回项目,节省了第二次查找以获取值。您没有看到这种改进吗?
-
您可以使用 .NET Reflector 查看实际实现。但老实说,也许你的算法是问题所在。你需要做那么多查找吗?
标签: c# .net algorithm performance hashtable