store icon indicating copy to clipboard operation
store copied to clipboard

Peek: Benchmark Ptr-Length-Offset instead of Ptr-Ptr

Open Mathnerd314 opened this issue 9 years ago • 0 comments

If the type of Peek was

type Offset = Int
type Length = Int
newtype Peek = Peek { runPeek :: forall byte. Ptr byte -> Length -> IO (Offset, a) }

then most pointer subtractions and additions could be avoided; for example:

peekStorableTy ty = Peek $ \ptr blen ->
    let needed = sizeOf (undefined :: a)
     in do
        when (needed > blen) $
            tooManyBytes needed blen ty
        x <- Storable.peek (castPtr ptr)
        return (needed, x)

peekToPlainForeignPtr ty len =
    Peek $ \sourcePtr sourceLen -> do
        when (len > sourceLen) $
            tooManyBytes len sourceLen ty
        fp <- BS.mallocByteString len
        withForeignPtr fp $ \targetPtr ->
            BS.memcpy targetPtr (castPtr sourcePtr) len
        return (len, castForeignPtr fp)

They would move into the Peek monad:

    pure x = Peek (\_ _ -> return (0, x))
    Peek x >>= f = Peek $ \ptr blen -> do
        (off, x') <- x ptr blen
        runPeek (f x') (ptr `plusPtr` off) (blen - off)

The performance of the two Peek types should be close. But I thought I should ask before setting up the benchmark, in case this approach has already been considered.

Mathnerd314 avatar Jul 08 '16 05:07 Mathnerd314