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

时间:2016-10-21 12:26:32

标签: haskell haskell-vector

所以...我已经使用了未装箱的载体(来自vector包),现在最好不要考虑它。 vector-th-unbox为他们创建实例变得轻而易举,为什么不呢。

现在我遇到了一个实例,我无法自动派生这些实例,这是一个带有幻像类型参数的数据类型(如Vector (s :: Nat) a,其中s编码长度)。< / p>

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

  • Unboxed将元组存储为单独的向量,从而在不需要其中一个值的情况下浪费带宽,从而实现更好的缓存局部性。
  • Storable仍将被编译为简单(可能是高效的)readArray#,它们会返回未装箱的值(通过阅读核心就可以看出)。
  • Storable允许直接指针访问,允许与外部代码互操作。 Unboxed没有。
  • [edit] Storable实例实际上比UnboxVectorMVector)更容易手写。

仅凭这一点并不能说明为什么Unboxed甚至存在,似乎没什么好处。可能我错过了什么?

2 个答案:

答案 0 :(得分:14)

来自vue-validator

可存储和未装箱的矢量都将其数据存储在字节数组中,从而避免了这种情况 指针间接。这样可以提高内存效率,并且可以更好地使用 缓存。可存储和无框矢量之间的区别很微妙:

  • 可存储的向量需要数据,这是https://haskell-lang.org/library/vector的一个实例。 此数据存储在malloc内存中,固定(垃圾 收藏家不能移动它。这可能导致内存碎片,但是 允许通过C FFI共享数据。
  • 未装箱的向量需要数据,这是Storable type class的一个实例。 此数据存储在GC管理的 unpinned 内存中,这有助于避免内存 碎片。但是,此数据无法通过C FFI共享。

StorablePrim类型类提供了一种将值存储为的方法 字节,并将字节加载到一个值。区别在于什么类型 使用了bytearray。

与往常一样,唯一真正的绩效衡量标准是基准测试。然而, 作为一般准则:

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

还有其他需要考虑的问题,例如盒装矢量这一事实 是Functor的实例,而可存储和未装箱的矢量则不是。{/ p>

答案 1 :(得分:0)

另一个区别是内存开销:

根据我的测量:

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

来源: