【问题标题】:Is It Possible to Use Hashcodes as a Bitmask to Efficiently Store/Track Collection Membership?是否可以使用哈希码作为位掩码来有效地存储/跟踪集合成员资格?
【发布时间】:2016-06-20 18:30:17
【问题描述】:

目前我有一个解决方案,通过Object.GetHashCode 获取它们的哈希码,然后将它们存储在HashSet<int> 中,我可以跟踪我感兴趣的对象。

不过,我也一直在学习位掩码和位运算,我对它们很感兴趣。 Here is a great question 我发现这与我想做的事情很接近。但是,对于哈希码,我似乎无法有效地进行这项工作。

There is also this question,但是当哈希码是int(32 位)时,它似乎可以处理 5 位数字。

我确实得到了BitArray 解决方案(来自第一个引用的问题),但它没有我目前的 HashSet 方法那么快。这是因为BitArray 中的项目数量庞大,需要创建这些项目以说明所有已知的哈希码 (int.MaxValue)。

在使用BitArray 进行这项工作时,我应该考虑一些位掩码/按位操作吗?还是我在这里完全偏离了常规,应该坚持我的HashSet<int> 解决方案?

【问题讨论】:

  • 请不要使用 gethashcode,很容易发生冲突! stackoverflow.com/questions/7968753/…
  • 您应该将对象本身存储在HashSet 中,而不是存储它们的GetHashCode 值。通过仅存储哈希值,您可以消除HashSet 管理冲突的能力。至于问题的其余部分,它基于散列对于每个对象都是唯一的前提,但这是一个错误的假设,所以你不能这样做。只需将项目放入HashSet
  • @Servy 这是一个很好的观点,你让我在这里重新考虑我的设计。我希望存储信息而不必在内存中创建对对象的强引用并使其尽可能快。听起来我已经找到了解决方案(只要确保我找到了!)。
  • @Mike-EEE 您可以创建对它的弱引用,但要不完全引用它,您需要让它生成一个已知对该对象始终唯一的值,这将永不碰撞。 GetHashCode 不会那样做;它需要提供一些其他更强大的散列形式。
  • @Servy 正确。问题(据我所知)是这些对象也可以是结构,它们不适用于WeakReference,或者至少不适用于WeakReference<T>。我会考虑更多。

标签: c# .net hashcode hashset bitmask


【解决方案1】:

这确实是一个不走寻常路的例子,伴随着对引用/内存管理的误解。在我的例子中,我使用Dictionary<TKey, TValue> 对象来存储实例上方法调用的缓存结果。我不能使用ConditionalWeakTable,因为一个键至少包含三个部分:

  1. 包含缓存结果的方法的实例。
  2. 上述方法。
  3. 正在传递给方法的参数。

如果我使用ConditionalWeakTable,我将不得不创建“​​又一个对象”(类),这将需要另一个分配,但更糟糕的是,它不会被任何东西引用(除了ConditionalWeakTable)并且会得到垃圾在第一遍收集(这确实是related to another open -- but now also solved -- question of mine)。

经过深思熟虑,我意识到答案确实在于ConditionalWeakTable。答案是使用由第 1 部分和第 2 部分组成的 Delegate,然后将 Dictionary 与之配对,而不是使用上述 3 项作为键。

或者作为一个字段初始化:

readonly ConditionalWeakTable<Delegate, Dictionary<object[], object>> cache = new ConditionalWeakTable<Delegate, Dictionary<object[], object>>();

(另外值得注意的是使用StructuralEqualityComparer 和上述字典来完成这项工作)。

这当然可以满足我的所有需求。它将跟踪对象,直到从内存中清除包含该方法(以及包含 Delegate 的方法)的引用对象。此时,缓存的字典也将被释放,清除其所有内容。

【讨论】:

    猜你喜欢
    • 2010-11-07
    • 2015-02-10
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    相关资源
    最近更新 更多