数据StableName a
稳定名称具有以下属性:
如果sn1::StableName和sn2::StableName和sn1 == sn2,则sn1和sn2是通过在同一对象上调用makeStableName创建的。
相反的情况不一定成立:如果两个稳定名称不相等,则它们命名的对象可能仍然相等。
reallyUnsafePtrEquality#::a-> a-> Int#
trueUnsafePtrEquality#返回GHC堆上的两个对象是否为同一对象。这确实是不安全的,因为垃圾收集器会移动,关闭等内容。据我所知,它可以返回假阴性(它说两个对象不相同,但它们是相同的),但不能返回假阳性(说它们如果不是,则相同)。
它们似乎都执行相同的基本操作:它们可以告诉您两个对象是否绝对相同,而不能告诉您它们是否绝对不相同。
我可以看到StableNames的优点是:
我可以看到的真正unsafePtrEquality#的优点:
我的问题是:
最佳答案
持有对象的StableName
不会阻止对其进行垃圾回收,而持有对象本身(稍后将其与reallyUnsafePtrEquality#
结合使用)却可以。当然,您可以使用 System.Mem.Weak
,但是到那时,为什么不只使用StableName
呢? (实际上,弱指针已添加到StableName
中。)
能够散列它们是StableName
的主要动机,如文档所述:
我们不能使用对象的地址作为键来构建哈希表,因为对象会被垃圾回收器移动,这意味着在每次垃圾回收之后都需要重新哈希。
通常,如果StableName
可以满足您的目的,即使您需要使用unsafePerformIO
,我也会使用它们;如果您确实需要reallyUnsafePtrEquality#
,那么您会知道的。我可以想到的唯一示例是reallyUnsafePtrEquality#
在哪里工作,而StableName
在哪里不行,这是在加快昂贵的Eq
实例的速度:
x == y =
x `seq` y `seq`
case reallyUnsafePtrEquality# x y of
1# -> True
_ -> slowEq x y
我可能还没有想到其他示例,但是它们并不常见。
关于haskell - StableNames相对于trueUnsafePtrEquality#有什么优势,反之亦然?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9649500/