3

I have a data type of the form:

data T = { a :: Int, b :: ComplexOtherDataType }

I can obviously put these into regular vectors from the Data.Vector module. But I want really, really good performance when I access the a component, so the extra indirection is undesirable. What I want to do is make T an instance of Data.Vector.Unboxed.Unbox, but still have b be lazy.

The vector-th-unbox provides a nice template haskell interface for making instances of Unbox, but it won't work in my case. It requires that in order to make T an instance of Unbox, both a and b must also be instances. But I don't want to unbox b. I want it to be boxed/lazy.

My intuition says that the easiest way to overcome this obstacle is by providing a type

newtype LazyUnbox a = LazyUnbox a

Then, I need to provide an Unbox instance for LazyUnbox that will basically just store a pointer inside the unboxed vector. How can I do this? Or is there a better approach entirely?

4

2 回答 2

10

您如何想象“将指针存储为拆箱”(即机器字)值?据我所知,GHC 运行时不允许获取指向托管结构的指针。

权衡解决方案是制作自己的VG.Vector实例,例如。

data TVector = TVector (VU.Vector Int) (V.Vector ComplexOtherDataType)

instance VG.Vector TVector T where
    basicUnsafeIndexM (TVector va vb) i = do
        a <- basicUnsafeIndexM va i
        b <- basicUnsafeIndexM vb i
        return (T a b)
    ...

VU.Vector Int您可以在需要时提取未装箱的部分。

于 2013-06-24T03:36:59.913 回答
1

Edward Kmett 写了一篇文章来解释如何做这件事: https ://www.schoolofhaskell.com/user/edwardk/revisiting-matrix-multiplication/part-3 我不明白为什么第二个字段在他的代码中仍然被装箱,但我确信它有效。是hybrid-vectors包裹。

于 2015-04-17T21:08:26.563 回答