首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >F#中的哈希计算和.net中的弱哈希表

F#中的哈希计算和.net中的弱哈希表
EN

Stack Overflow用户
提问于 2013-03-25 22:11:15
回答 1查看 880关注 0票数 17

Hash-consing在于在内存中只保留给定对象的一个副本;也就是说,如果两个对象在语义上相等(相同的内容),那么它们在物理上应该是相等的(内存中的相同位置)。该技术通常通过保持全局散列集并仅在它们不等于散列集中的对象时创建新对象来实现。

一个额外的要求是,如果哈希表中的对象没有被哈希表以外的任何东西引用,那么它们应该是可收集的;否则,哈希表应该包含弱引用。

此外,由于需要具有恒定的时间,因此需要进行浅层、散列和相等性测试,因此该问题变得更加复杂;因此,对象具有唯一的标识符,该标识符在将新对象添加到表中时会递增。

我有一个使用System.Collections.Generic.Dictionary<key, node>的有效实现,其中key是一个元组,给出节点的浅层摘要(适用于默认哈希和相等性测试),node是对象。唯一的问题是Dictionary保持了对节点的强引用!

我可以使用WeakReferenceDictionary,但这不会释放指向悬空引用的键。

一些人提倡使用System.Runtime.CompilerServices.ConditionalWeakTable,但这个类似乎做了相反的事情:它在收集键时释放值,而我需要在收集值时释放键。

可以尝试使用System.Runtime.CompilerServices.ConditionalWeakTable<node, node>,但我需要自定义散列和相等性测试……并且ConditionalWeakTable被记录为不使用GetHashCode()虚拟方法,而是使用默认的散列函数。

因此,我的问题是:有没有Dictionary的等价物,当引用变得悬空时,它会保留弱引用并释放键?

EN

回答 1

Stack Overflow用户

发布于 2013-03-28 00:06:34

你说得对,CWT没有解决散列一致的问题,因为它回避了这个问题--它的键假定引用相等。然而,可能值得指出的是,CWT并不保留键或值。下面是一个小测试:

open System.Collections.Generic
open System.Runtime.CompilerServices

let big () =
    ref (Array.zeroCreate (1024 * 1024) : byte [])

let test1 () =
    let d = Dictionary(HashIdentity.Reference)
    for i in 1 .. 10000 do
        stdout.WriteLine(i)
        let big = big ()
        d.Add(big, big)
    d

let test2 () =
    let d = ConditionalWeakTable()
    for i in 1 .. 10000 do
        stdout.WriteLine(i)
        let big = big ()
        d.Add(big, big)
    d

在我的机器上,test1耗尽内存,而test2成功。这似乎只有在CWT没有抓住键和值的情况下才会发生。

对于hash-consing,您最好的选择可能是Artem在评论中提出的建议。如果这听起来太复杂,那么将控制权交给用户也很有意义,比如:

let f = MyFactory() // a dictionary with weak reference values hidden inside
f.Create(..) : MyObject // MyObject has no constructors of its own
f.Cleanup() // explicitly cleans up entries for collected keys 

这样您就不需要介绍线程、研究GC内部是如何工作的,也不需要施展任何魔法了。库的用户可以决定在哪里进行适当的清理,或者干脆“忘记”工厂对象--这将收集整个表。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15617073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档