C#中带有两个哈希函数的字典?

时间:2009-11-23 16:45:28

标签: c# hash dictionary

我有一个巨大的(>>>>>&n;&m;&#;每个条目都提供两个哈希函数:

  • 便宜:快速计算哈希值,但其分布很糟糕(可能将99%的项目放在1%的哈希空间中)
  • 昂贵:需要花费大量时间进行计算,但分布也要好得多

普通的词典让我只使用其中一个哈希函数。我想要一个首先使用廉价哈希函数的字典,并在碰撞中检查昂贵的哈希函数。

在这个词典中使用字典似乎是一个好主意。我目前基本上使用这种怪物:

Dictionary<int, Dictionary<int, List<Foo>>>;

我改进了这个设计,所以只有当实际上有两个相同的廉价哈希项时才会调用昂贵的哈希值。

它完全适合我,并为我做了完美的工作,但它看起来应该已经死了6500万年前。

据我所知,此功能未包含在基本框架中。我即将写一个DoubleHashedDictionary类,但我想先了解你的意见。

至于我的具体情况:
第一个哈希函数=文件系统目录中的文件数(快) 第二个哈希函数=文件大小的总和(慢)

编辑:

  • 更改了标题并添加了更多信息。
  • 添加了非常重要的缺失细节

4 个答案:

答案 0 :(得分:2)

在你的情况下,你在技术上使用修改过的函数(A | B),而不是双曲线。但是,根据您的“巨大”条目列表的大小以及数据的特征,请考虑以下因素:

  • 具有不太好的分布的20%完整哈希表可能有超过80%的冲突机会。这意味着您的预期功能成本可能是:(0.8昂贵+ 0.2便宜)+(查找成本)。因此,如果您的餐桌超过20%,则可能不值得使用(A | B)计划。

  • 可以使用完美的哈希函数,但是O(n ^ 3)会使其变得不切实际。

  • 如果性能非常重要,您可以通过测试关键数据上的各种哈希函数,为特定数据制作专门调整的哈希表。

答案 1 :(得分:1)

您是否看过Power CollectionsC5 Collections图书馆? Power Collections库最近没有太多动作,但C5的东西似乎是相当最新的。

我不确定这两个库是否具有您需要的功能,但它们非常有用且它们是开源的,因此它可以为您提供一个合适的基础实现,以扩展到您所需的功能。

答案 2 :(得分:1)

你基本上是在谈论哈希表的哈希表,每个哈希表都使用不同的GetHashCode实现......虽然我认为你可能会认真考虑一下你是否真的会在只做一个或者其他......

实际上是否会有大量的对象通过快速哈希机制定位,而不必采用更昂贵的对象进一步缩小范围?因为如果你不能完全从第一次计算中找到大量的数据,你就可以分两步完成任务(不知道数据是否很难预测是否是这种情况)。

如果它在一个步骤中成为一个重要的数量,那么你可能需要进行一些调整以计算出在外部的每个散列位置上存储多少记录然后才能使用内部“昂贵的“散列表查找,而不是对散列数据的更多处理,但在某些情况下,我可以看到你如何从中获得性能提升(情况很少,但很难,但不是不可想象的。)

修改

我刚看到你对这个问题的修正 - 你打算不管怎样都进行两次查找...我怀疑你会从中获得任何性能上的好处,你不能仅仅通过更好地配置主哈希表来获得。您是否尝试使用构造函数中传递了适当容量的单个字典,并且可能将两个哈希代码的XOR作为哈希代码?

答案 3 :(得分:1)

首先,我认为你正在实现自己的散列表的正确道路,如果你所描述的是真正需要的。但作为评论家,我想问几个问题:

您是否考虑过为每个条目使用更独特的内容?

我假设每个条目都是文件系统目录信息,您是否考虑过使用其完整路径作为密钥?用计算机名/ IP地址加前缀?

另一方面,如果您使用多个文件作为哈希键,这些目录是否永远不会改变?因为如果散列键/结果发生变化,您将永远无法再找到它。

在这个主题上,如果目录内容/大小永远不会改变,你可以将该值存储在某处以节省实际计算时间吗?

只需几分钱。