Haskell StableNames与真正不安全的要求相比有什么优势?反之亦然?
数据a 稳定名称具有以下属性: 如果sn1::StableName和sn2::StableName和sn1==sn2,那么sn1和sn2是通过调用同一对象上的makeStableName创建的 反之亦然:如果两个稳定的名称不相等,那么它们命名的对象可能仍然相等 ::a->a->Int#Haskell StableNames与真正不安全的要求相比有什么优势?反之亦然?,haskell,ghc,Haskell,Ghc,数据a 稳定名称具有以下属性: 如果sn1::StableName和sn2::StableName和sn1==sn2,那么sn1和sn2是通过调用同一对象上的makeStableName创建的 反之亦然:如果两个稳定的名称不相等,那么它们命名的对象可能仍然相等 ::a->a->Int# reallyUnsafePtrEquality#返回GHC堆上的两个对象是否为同一个对象。这真的很不安全,因为垃圾收集器会四处移动东西、闭包等。据我所知,它可以返回误报(它说两个对象不一样,但它们是一样的),但不
reallyUnsafePtrEquality#返回GHC堆上的两个对象是否为同一个对象。这真的很不安全,因为垃圾收集器会四处移动东西、闭包等。据我所知,它可以返回误报(它说两个对象不一样,但它们是一样的),但不会返回误报(说它们不一样时是一样的) 它们似乎都做了相同的基本事情:它们可以告诉你两个物体是否绝对相同,但不能告诉你它们是否绝对不一样 我可以看到StableNames的优点是:
- 它们可以散列
- 它们不那么容易携带
- 他们的行为得到了明确的定义和支持
- 他们没有真正的不安全作为他们名字的一部分
- 它可以直接在相关对象上调用,而不必创建单独的StablesNames
- 您不必通过IO函数来创建StableNames
- 您不必保留StableNames,因此内存使用率更低
- RTS不需要做任何使StableNames工作的魔法,因此性能可能更好
- 它的名字和结尾都很不安全。铁杆李>
- 我错过什么了吗
- 是否存在这样的用例:StableNames与它们命名的对象是分开的,这是一个优势
- 其中一个是否比另一个更准确(不太可能返回假阴性)
- 如果您不需要散列,不关心可移植性,也不为使用ReallySafetable而烦恼,那么有什么理由更喜欢StableNames而不是reallyUnsafePtrEquality
StableName
不会阻止它被垃圾收集,而保持对象本身(稍后与reallunsafeptrequality一起使用)会阻止垃圾收集。当然,您可以使用,但在这一点上,为什么不使用StableName
?(事实上,弱指针添加了StableName
s。)
能够散列它们是StableName
s的主要动力,正如文档所述:
我们不能使用对象的地址作为键来构建哈希表,因为对象会被垃圾收集器移动,这意味着每次垃圾收集后都需要重新哈希
一般来说,如果StableName
s符合您的目的,我会使用它们,即使您需要使用unsafePerformIO
;如果你真的需要真正的不安全性#
,你会知道的。我能想到的唯一一个例子是,reallunsafeptrequality#
能起作用,StableName
s不能起作用的是加速一个昂贵的Eq
实例:
x == y =
x `seq` y `seq`
case reallyUnsafePtrEquality# x y of
1# -> True
_ -> slowEq x y
可能还有其他我没有想到的例子,但它们并不常见。垃圾收集和System.Mem.Weak的优点。尽管我猜必然的结果是:在什么情况下,除了命名对象之外,您希望存储stablename?哈希表是一个,还有其他的吗?关于你的最后一点,你是否有任何具体的理由选择StableNames?(是否真的存在StableNames不合适的情况,以及真正不安全的情况?)@illissius:好吧,用哈希表记录是StableNames和薄弱点的主要原因,所以这是目前为止最突出的例子。它们对我来说也很有用。我更新了我的帖子,举了一个例子,说明reallunsafeptrequality#
什么时候可以工作,但是StableName
s就不行了。至于我为什么总的来说更喜欢它们,只是它们的行为更加一致,并且被设计成一个公共界面,这对我来说已经足够了。我会考虑直接跳到<代码> RealLySuffePrPosivs一个非常危险的排序的过早优化。在我看来,这里也没有任何东西可以排除使用StableNames的可能性(至少如果slowEq足够昂贵的话),但“我为什么要这样做,因为我可以使用真正的不安全性?”是这个问题的部分动机。但我们似乎在这里达成了一致。“据我所知,它可以返回假阴性(它说两个对象不一样,但它们是一样的),但不能返回假阳性(说它们不一样时它们是一样的)。”我担心,尽管这极不可能。我记不起在哪里讨论过(可能是IRC),但我记得为什么不可能出现误报的两个原因是GC只发生在分配时,而不是在初始操作时,所以它不可能中断真正不安全的请求——将一个对象放在另一个对象所在的位置;GC从空间到空间是不重叠的,所以即使可以,也不会重叠。显然,如果假阴性和假阳性都有可能的话,这将是完全无用的。这听起来似乎是有道理的。但通常爱德华·K.知道发生了什么,所以我宁愿仔细检查,也不愿轻率地忽略他的警告。然而,第二点几乎排除了误报(两个GCs在查看两个ARG之间的初始值似乎有点牵强),即使一个人不完全相信第一个。如果我没有记错的话,爱德华K.实际上是我提到的讨论的一部分。:)如果我找到了,我会链接它。