store
store copied to clipboard
Peek: Benchmark Ptr-Length-Offset instead of Ptr-Ptr
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.