我想存储一个非参数,解压缩的数据类型
data Point3D = Point3D {-# UNPACK #-} !Int {-# UNPACK #-} !Int {-# UNPACK #-} !Int
在未装箱的矢量中. Data.Vector.Unboxed说:
In particular,unBoxed vectors of pairs are represented as pairs of unBoxed vectors.
这是为什么?我希望我的Point3D在内存中一个接一个地布局,以便在顺序迭代它们时获得快速缓存本地访问 – 相当于C中的mystruct [1000].
使用Vector.UnBoxed或其他方式,我该如何实现?
顺便说一下:使用vector-th-unbox也是如此,因为你只需将数据类型转换为(UnBox a,UnBox b)=> UnBox(a,b)instance.
解决方法
我不知道为什么对的向量存储为向量对,但是您可以轻松地为您的数据类型编写实例以按顺序存储元素.
{-# LANGUAGE TypeFamilies,MultiParamTypeClasses #-} import qualified Data.Vector.Generic as G import qualified Data.Vector.Generic.Mutable as M import Control.Monad (liftM,zipWithM_) import Data.Vector.UnBoxed.Base data Point3D = Point3D {-# UNPACK #-} !Int {-# UNPACK #-} !Int {-# UNPACK #-} !Int newtype instance MVector s Point3D = MV_Point3D (MVector s Int) newtype instance Vector Point3D = V_Point3D (Vector Int) instance UnBox Point3D
此时,最后一行将导致错误,因为Point3D没有矢量类型的实例.它们可以写成如下:
instance M.MVector MVector Point3D where basicLength (MV_Point3D v) = M.basicLength v `div` 3 basicUnsafeSlice a b (MV_Point3D v) = MV_Point3D $M.basicUnsafeSlice (a*3) (b*3) v basicOverlaps (MV_Point3D v0) (MV_Point3D v1) = M.basicOverlaps v0 v1 basicUnsafeNew n = liftM MV_Point3D (M.basicUnsafeNew (3*n)) basicUnsafeRead (MV_Point3D v) n = do [a,b,c] <- mapM (M.basicUnsafeRead v) [3*n,3*n+1,3*n+2] return $Point3D a b c basicUnsafeWrite (MV_Point3D v) n (Point3D a b c) = zipWithM_ (M.basicUnsafeWrite v) [3*n,3*n+2] [a,c] instance G.Vector Vector Point3D where basicUnsafeFreeze (MV_Point3D v) = liftM V_Point3D (G.basicUnsafeFreeze v) basicUnsafeThaw (V_Point3D v) = liftM MV_Point3D (G.basicUnsafeThaw v) basicLength (V_Point3D v) = G.basicLength v `div` 3 basicUnsafeSlice a b (V_Point3D v) = V_Point3D $G.basicUnsafeSlice (a*3) (b*3) v basicUnsafeIndexM (V_Point3D v) n = do [a,c] <- mapM (G.basicUnsafeIndexM v) [3*n,3*n+2] return $Point3D a b c
我认为大多数函数定义都是自解释的.点矢量存储为Ints的矢量,第n点是3n,3n 1,3n 2 Ints.