繁体   English   中英

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

[英]Dictionary with two hash functions in C#?

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

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

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

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

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

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

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

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

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

编辑:

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

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

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

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

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

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

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

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

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

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

编辑

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

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

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

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

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

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

只是我的几美分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM