Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell StableNames与真正不安全的要求相比有什么优势?反之亦然?_Haskell_Ghc - Fatal编程技术网

Haskell StableNames与真正不安全的要求相比有什么优势?反之亦然?

Haskell StableNames与真正不安全的要求相比有什么优势?反之亦然?,haskell,ghc,Haskell,Ghc,数据a 稳定名称具有以下属性: 如果sn1::StableName和sn2::StableName和sn1==sn2,那么sn1和sn2是通过调用同一对象上的makeStableName创建的 反之亦然:如果两个稳定的名称不相等,那么它们命名的对象可能仍然相等 ::a->a->Int# reallyUnsafePtrEquality#返回GHC堆上的两个对象是否为同一个对象。这真的很不安全,因为垃圾收集器会四处移动东西、闭包等。据我所知,它可以返回误报(它说两个对象不一样,但它们是一样的),但不

数据a

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

反之亦然:如果两个稳定的名称不相等,那么它们命名的对象可能仍然相等

::a->a->Int#


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.实际上是我提到的讨论的一部分。:)如果我找到了,我会链接它。