问题描述
数据 a
$ b
一般来说,如果 StableName
s可以用于您的目的,即使您需要使用 unsafePerformIO
;如果你真的需要 reallyUnsafePtrEquality#
,你就会知道。我能想到的唯一例子是 reallyUnsafePtrEquality#
会起作用, StableName
s不会加速昂贵的 Eq
instance:
x == y =
x`seq `y`seq`
case reallyUnsafePtrEquality#xy of
1# - > True
_ - > slowEq xy
我可能还没有想到其他的例子,但它们并不常见。
data StableName a
reallyUnsafePtrEquality# :: a -> a -> Int#
reallyUnsafePtrEquality# returns whether two objects on the GHC heap are the same object. It's really unsafe because the garbage collector moves things around, closures, etc. To the best of my knowledge, it can return false negatives (it says two objects aren't the same, but they are), but not false positives (saying they're the same when they aren't).
Both of them seem to do the same basic thing: they can tell you whether two objects are definitely the same, but not whether they're definitely not.
The advantages I can see for StableNames are:
- They can be hashed.
- They are less nonportable.
- Their behaviour is well-defined and supported.
- They don't have reallyUnsafe as part of their name.
The advantages I can see for reallyUnsafePtrEquality#:
- It can be called directly on the objects in question, instead of having to create separate StablesNames.
- You don't have to go through an IO function to create the StableNames.
- You don't have to keep StableNames around, so memory usage is lower.
- The RTS doesn't have to do whatever magic it does to make the StableNames work, so performance is presumably better.
- It has reallyUnsafe in the name and a # at the end. Hardcore!
My questions are:
Did I miss anything?
Is there any use case where the fact that StableNames are separate from the objects they name is an advantage?
Is either one more accurate (less likely to return false negatives) than the other?
If you don't need hashing, don't care about portability, and aren't bothered by using something called reallyUnsafe, is there any reason to prefer StableNames over reallyUnsafePtrEquality#?
Holding the StableName
of an object doesn't prevent it from being garbage collected, whereas holding the object itself around (to use with reallyUnsafePtrEquality#
later) does. Sure, you can use System.Mem.Weak
, but at that point, why not just use a StableName
? (In fact, weak pointers were added with StableName
s.)
Being able to hash them is the main motivator for StableName
s, as the documentation says:
In general, if StableName
s will work for your purposes, I'd use them, even if you need to use unsafePerformIO
; if you really need reallyUnsafePtrEquality#
, you'll know. The only example I can think of where reallyUnsafePtrEquality#
would work and StableName
s wouldn't is speeding up an expensive Eq
instance:
x == y =
x `seq` y `seq`
case reallyUnsafePtrEquality# x y of
1# -> True
_ -> slowEq x y
There's probably other examples I just haven't thought of, but they're not common.
这篇关于StableNames对真正的不安全性质量有什么优势,反之亦然?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!