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

fho*_*fho 9 haskell haskell-vector

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

现在我遇到了一个实例,我无法自动派生那些实例,一个带有幻像类型参数的数据类型(如Vector (s :: Nat) a,s编码长度).

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

  • Unboxed 将元组存储为单独的向量,从而导致更好的高速缓存局部性,而不需要在仅需要其中一个值时浪费带宽.
  • Storable仍将编译为简单(可能有效)的readArray#s,返回未装箱的值(通过阅读核心显而易见).
  • Storable允许直接指针访问,允许与外部代码的互操作性.Unboxed没有.
  • [编辑] Storable实例实际上是更容易用手比写Unbox(即VectorMVector)的.

仅仅这一点并没有让我明白为什么Unboxed即使存在,似乎也没什么好处.可能我错过了那里的东西?

Mic*_*man 16

来自https://haskell-lang.org/library/vector

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

  • 可存储的向量需要数据,该数据是Storable类型类的实例.此数据存储在malloced内存中,该内存被固定(垃圾收集器无法移动它).这可能导致内存碎片,但允许通过C FFI共享数据.
  • 未装箱的向量需要数据,该数据是Prim类型类的实例.此数据存储在GC管理的未固定内存中,这有助于避免内存碎片.但是,此数据无法通过C FFI共享.

无论是StorablePrim类型类提供一种方法来存储一个值作为字节,并以字节加载到一个值.区别在于使用什么类型的bytearray.

像往常一样,唯一真正的绩效衡量标准是基准测试.但是,作为一般准则:

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

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