可存储和未装箱矢量之间的差异
Differences between Storable and Unboxed Vectors
所以...我现在最好使用未装箱的矢量(来自 vector
包)而没有过多考虑。 vector-th-unbox
为他们创建实例变得轻而易举,为什么不呢。
现在我 运行 进入一个我无法自动派生这些实例的实例,一个带有幻像类型参数的数据类型(如 Vector (s :: Nat) a
,其中 s
编码长度)。
这让我想到了 Storable
和 Unboxed
向量之间的区别。我自己想出的事情:
Unboxed
会将例如元组存储为单独的向量,从而在只需要其中一个值时不浪费带宽,从而实现更好的缓存局部性。
Storable
仍将被编译为简单的(并且可能有效)readArray#
s return 未装箱的值(通过阅读核心显而易见)。
Storable
允许直接指针访问,这允许与外部代码的互操作性。 Unboxed
没有。
- [edit]
Storable
实例实际上比 Unbox
(即 Vector
和 MVector
)更容易手写。
仅此一点并不能使我明白为什么 Unboxed
甚至存在,它似乎没有什么好处。可能我在那里遗漏了什么?
抄袭自 https://haskell-lang.org/library/vector
可存储向量和未装箱向量都将其数据存储在字节数组中,避免
指针间接。这样内存效率更高,可以更好地使用
缓存。可存储向量和未装箱向量之间的区别很微妙:
- 可存储向量需要数据,该数据是
Storable
类型的实例
class。
此数据存储在 malloc
ed 内存中,即 pinned(垃圾
收藏家无法移动它)。这会导致内存碎片,但是
允许通过 C FFI 共享数据。
- 未装箱的向量需要数据,该数据是
Prim
类型的实例
class。
此数据存储在GC-managedunpinned内存中,有助于避免内存
碎片化。但是,无法通过 C FFI 共享此数据。
Storable
和 Prim
类型class 都提供了一种将值存储为
字节,并将字节加载到一个值中。区别是什么类型的
使用字节数组。
像往常一样,唯一真正衡量性能的方法是基准测试。然而,
作为一般准则:
- 如果您不需要将值传递给 C FFI,并且您有一个
Prim
实例,
使用未装箱的矢量。
- 如果您有
Storable
个实例,请使用可存储向量。
- 否则,使用盒装矢量。
还有其他问题需要考虑,例如盒装向量
是 Functor
的实例,而可存储和未装箱的向量不是。
另一个区别是内存开销:
根据我的测量:
Data.Vector.Storable.Vector Int
有 64 字节开销
Data.Vector.Unboxed.Vector Int
有 48 字节开销。
来源:
所以...我现在最好使用未装箱的矢量(来自 vector
包)而没有过多考虑。 vector-th-unbox
为他们创建实例变得轻而易举,为什么不呢。
现在我 运行 进入一个我无法自动派生这些实例的实例,一个带有幻像类型参数的数据类型(如 Vector (s :: Nat) a
,其中 s
编码长度)。
这让我想到了 Storable
和 Unboxed
向量之间的区别。我自己想出的事情:
Unboxed
会将例如元组存储为单独的向量,从而在只需要其中一个值时不浪费带宽,从而实现更好的缓存局部性。Storable
仍将被编译为简单的(并且可能有效)readArray#
s return 未装箱的值(通过阅读核心显而易见)。Storable
允许直接指针访问,这允许与外部代码的互操作性。Unboxed
没有。- [edit]
Storable
实例实际上比Unbox
(即Vector
和MVector
)更容易手写。
仅此一点并不能使我明白为什么 Unboxed
甚至存在,它似乎没有什么好处。可能我在那里遗漏了什么?
抄袭自 https://haskell-lang.org/library/vector
可存储向量和未装箱向量都将其数据存储在字节数组中,避免 指针间接。这样内存效率更高,可以更好地使用 缓存。可存储向量和未装箱向量之间的区别很微妙:
- 可存储向量需要数据,该数据是
Storable
类型的实例 class。 此数据存储在malloc
ed 内存中,即 pinned(垃圾 收藏家无法移动它)。这会导致内存碎片,但是 允许通过 C FFI 共享数据。 - 未装箱的向量需要数据,该数据是
Prim
类型的实例 class。 此数据存储在GC-managedunpinned内存中,有助于避免内存 碎片化。但是,无法通过 C FFI 共享此数据。
Storable
和 Prim
类型class 都提供了一种将值存储为
字节,并将字节加载到一个值中。区别是什么类型的
使用字节数组。
像往常一样,唯一真正衡量性能的方法是基准测试。然而, 作为一般准则:
- 如果您不需要将值传递给 C FFI,并且您有一个
Prim
实例, 使用未装箱的矢量。 - 如果您有
Storable
个实例,请使用可存储向量。 - 否则,使用盒装矢量。
还有其他问题需要考虑,例如盒装向量
是 Functor
的实例,而可存储和未装箱的向量不是。
另一个区别是内存开销:
根据我的测量:
Data.Vector.Storable.Vector Int
有 64 字节开销Data.Vector.Unboxed.Vector Int
有 48 字节开销。
来源: