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

我有一个巨大的(>> 10米)条目列表。 每个条目都提供两个哈希函数:

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

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

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

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

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

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

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

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

编辑:

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

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

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

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

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

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

只是我的几美分。

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

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

  • 提出一个完美的哈希函数是可能的,但是O(n ^ 3)使得它不切实际。

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

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

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

你基本上是在谈论哈希表的哈希表,每个哈希表都使用不同的GetHashCode实现…虽然我认为你可能会认真考虑你是否真的会在仅仅做一个或另一个时获得性能提升…

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

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

编辑

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