Create strict bytestrings from FixedPrim with zero copy
- Dominant language
- Haskell
- Stars
- 301
- Forks
- 144
- Avg merge
- 7d 22h
- Merged PRs (30d)
- 1
Description
To turn a FixedPrim into a strict ByteString, with the current public interface I can do something like this:
```
myTypePrim :: FixedPrim MyType
myTypeToLazyByteString :: MyType -> BL.ByteString
myTypeToLazyByteString =
-- Some kind of allocation strategy to create a chunk of desired size
BB.toLazyByteStringWith (BB.untrimmedStrategy 36 BB.defaultChunkSize) mempty
. BBP.primFixed myTypePrim
-- Makes a copy with memcmp
myTypeToStrictByteString :: MyType -> BS.ByteString
myTypeToStrictByteString = toStrict . myTypeToLazyByteString
```
Once `primFixed :: FixedPrim a -> a -> Builder` converts a value to `Builder`, there are only utilities to convert it into a lazy bytestring.
One alternative is to use `runF :: FixedPrim a -> a -> Ptr Word8 -> IO ()` together with `create :: create :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString` but that relies on two internal modules `Data.ByteString.Builder.Prim.Internal` and `Data.ByteString.Internal`.
I propose three solutions:
1. Create function `Builder -> Ptr Word8 -> IO ()`
2. Export `runF :: FixedPrim a -> a -> Ptr Word8 -> IO ()` from the public module `Data.ByteString.Builder.Prim`.
3. Create function `primToByteString :: FixedPrim a -> a -> ByteString` that creates a strict bytestring right away.
For both 1 and 2 the code would rely on the `create` from the semi-public module `Data.ByteString.Internal`.
For the context, the benchmarking in https://github.com/haskell-hvr/uuid/pull/80 shows that the overhead of copy from `toStrict` slows down the conversion by 40% (28ns vs 20ns).
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.