haskell / haskell/bytestring

Create strict bytestrings from FixedPrim with zero copy

Open
#666 6 comments 0 reactions 0 assignees View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.