可存储和未装箱矢量之间的差异

Differences between Storable and Unboxed Vectors

所以...我现在最好使用未装箱的矢量(来自 vector 包)而没有过多考虑。 vector-th-unbox 为他们创建实例变得轻而易举,为什么不呢。

现在我 运行 进入一个我无法自动派生这些实例的实例,一个带有幻像类型参数的数据类型(如 Vector (s :: Nat) a,其中 s编码长度)。

这让我想到了 StorableUnboxed 向量之间的区别。我自己想出的事情:

仅此一点并不能使我明白为什么 Unboxed 甚至存在,它似乎没有什么好处。可能我在那里遗漏了什么?

抄袭自 https://haskell-lang.org/library/vector

可存储向量和未装箱向量都将其数据存储在字节数组中,避免 指针间接。这样内存效率更高,可以更好地使用 缓存。可存储向量和未装箱向量之间的区别很微妙:

  • 可存储向量需要数据,该数据是 Storable 类型的实例 class。 此数据存储在 malloced 内存中,即 pinned(垃圾 收藏家无法移动它)。这会导致内存碎片,但是 允许通过 C FFI 共享数据。
  • 未装箱的向量需要数据,该数据是 Prim 类型的实例 class。 此数据存储在GC-managedunpinned内存中,有助于避免内存 碎片化。但是,无法通过 C FFI 共享此数据。

StorablePrim 类型class 都提供了一种将值存储为 字节,并将字节加载到一个值中。区别是什么类型的 使用字节数组。

像往常一样,唯一真正衡量性能的方法是基准测试。然而, 作为一般准则:

  • 如果您不需要将值传递给 C FFI,并且您有一个 Prim 实例, 使用未装箱的矢量。
  • 如果您有 Storable 个实例,请使用可存储向量。
  • 否则,使用盒装矢量。

还有其他问题需要考虑,例如盒装向量 是 Functor 的实例,而可存储和未装箱的向量不是。

另一个区别是内存开销:

根据我的测量:

  • Data.Vector.Storable.Vector Int 有 64 字节开销
  • Data.Vector.Unboxed.Vector Int 有 48 字节开销。

来源: