数据StableName a

稳定名称具有以下属性:
如果sn1::StableName和sn2::StableName和sn1 == sn2,则sn1和sn2是通过在同一对象上调用makeStableName创建的。

相反的情况不一定成立:如果两个稳定名称不相等,则它们命名的对象可能仍然相等。

reallyUnsafePtrEquality#::a-> a-> Int#

trueUnsafePtrEquality#返回GHC堆上的两个对象是否为同一对象。这确实是不安全的,因为垃圾收集器会移动,关闭等内容。据我所知,它可以返回假阴性(它说两个对象不相同,但它们是相同的),但不能返回假阳性(说它们如果不是,则相同)。

它们似乎都执行相同的基本操作:它们可以告诉您两个对象是否绝对相同,而不能告诉您它们是否绝对不相同。

我可以看到StableNames的优点是:

  • 它们可以被散列。
  • 它们不太便携。
  • 他们的行为已得到明确定义并得到支持。
  • 他们的名字中没有真正不安全的东西。

  • 我可以看到的真正unsafePtrEquality#的优点:
  • 可以直接在有问题的对象上调用它,而不必创建单独的StablesName。
  • 您不必通过IO函数来创建StableName。
  • 您不必保留StableNames,因此内存使用量较低。
  • 为了使StableNames起作用,RTS不必做任何不可思议的事情,因此性能可能会更好。
  • 名称中的名称确实为Unsafe,末尾带有#。铁杆!

  • 我的问题是:
  • 我有什么想念吗?
  • 在任何用例中,StableNames与它们命名的对象是分开的事实是一个优势吗?
  • 中的一个比另一个准确吗(不太可能返回假阴性)?
  • 如果您不需要哈希,不关心可移植性,并且不因使用真正不安全的东西而烦恼,那么有没有理由比StableUnsafePtrEquality#更喜欢StableNames?
  • 最佳答案

    持有对象的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/

    10-10 09:23