Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the strict/lazy type synonyms for better generated documentation #628

Merged
merged 1 commit into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions Data/ByteString/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ For an /efficient implementation of an encoding/,
'Builder's support (a) by providing an /O(1)/ concatentation operation
and efficient implementations of basic encodings for 'Char's, 'Int's,
and other standard Haskell values.
They support (b) by providing their result as a lazy 'L.ByteString',
They support (b) by providing their result as a 'L.LazyByteString',
which is internally just a linked list of pointers to /chunks/
of consecutive raw memory.
Lazy 'L.ByteString's can be efficiently consumed by functions that
'L.LazyByteString's can be efficiently consumed by functions that
write them to a file or send them over a network socket.
Note that each chunk boundary incurs expensive extra work (e.g., a system call)
that must be amortized over the work spent on consuming the chunk body.
Expand Down Expand Up @@ -65,11 +65,11 @@ using some Unicode character encoding. However, this sacrifices performance
due to the intermediate 'String' representation being built and thrown away
right afterwards. We get rid of this intermediate 'String' representation by
fixing the character encoding to UTF-8 and using 'Builder's to convert
@Table@s directly to UTF-8 encoded CSV tables represented as lazy
'L.ByteString's.
@Table@s directly to UTF-8 encoded CSV tables represented as
'L.LazyByteString's.

@
encodeUtf8CSV :: Table -> L.ByteString
encodeUtf8CSV :: Table -> L.LazyByteString
encodeUtf8CSV = 'toLazyByteString' . renderTable

renderTable :: Table -> Builder
Expand Down Expand Up @@ -114,7 +114,7 @@ table = [map StringC strings, map IntC [-3..3]]
@

The expression @encodeUtf8CSV table@ results in the following lazy
'L.ByteString'.
'L.LazyByteString'.

>Chunk "\"hello\",\"\\\"1\\\"\",\"\206\187-w\195\182rld\"\n-3,-2,-1,0,1,2,3\n" Empty

Expand All @@ -137,7 +137,7 @@ We use the @criterion@ library (<http://hackage.haskell.org/package/criterion>)
> ]

On a Core2 Duo 2.20GHz on a 32-bit Linux,
the above code takes 1ms to generate the 22'500 bytes long lazy 'L.ByteString'.
the above code takes 1ms to generate the 22'500 bytes long 'L.LazyByteString'.
Looking again at the definitions above,
we see that we took care to avoid intermediate data structures,
as otherwise we would sacrifice performance.
Expand All @@ -148,7 +148,7 @@ For example,
>renderRow = mconcat . intersperse (charUtf8 ',') . map renderCell

Similarly, using /O(n)/ concatentations like '++' or the equivalent 'Data.ByteString.concat'
operations on strict and lazy 'L.ByteString's should be avoided.
operations on strict and 'L.LazyByteString's should be avoided.
The following definition of @renderString@ is also about 20% slower.

>renderString :: String -> Builder
Expand Down Expand Up @@ -264,11 +264,11 @@ import Foreign
import GHC.Base (unpackCString#, unpackCStringUtf8#,
unpackFoldrCString#, build)

-- | Execute a 'Builder' and return the generated chunks as a lazy 'L.ByteString'.
-- The work is performed lazy, i.e., only when a chunk of the lazy 'L.ByteString'
-- | Execute a 'Builder' and return the generated chunks as a 'L.LazyByteString'.
-- The work is performed lazy, i.e., only when a chunk of the 'L.LazyByteString'
-- is forced.
{-# NOINLINE toLazyByteString #-} -- ensure code is shared
toLazyByteString :: Builder -> L.ByteString
toLazyByteString :: Builder -> L.LazyByteString
toLazyByteString = toLazyByteStringWith
(safeStrategy L.smallChunkSize L.defaultChunkSize) L.Empty

Expand Down
8 changes: 4 additions & 4 deletions Data/ByteString/Builder/ASCII.hs
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,14 @@ floatHexFixed = P.primFixed P.floatHexFixed
doubleHexFixed :: Double -> Builder
doubleHexFixed = P.primFixed P.doubleHexFixed

-- | Encode each byte of a 'S.ByteString' using its fixed-width hex encoding.
-- | Encode each byte of a 'S.StrictByteString' using its fixed-width hex encoding.
{-# NOINLINE byteStringHex #-} -- share code
byteStringHex :: S.ByteString -> Builder
byteStringHex :: S.StrictByteString -> Builder
byteStringHex = P.primMapByteStringFixed P.word8HexFixed

-- | Encode each byte of a lazy 'L.ByteString' using its fixed-width hex encoding.
-- | Encode each byte of a 'L.LazyByteString' using its fixed-width hex encoding.
{-# NOINLINE lazyByteStringHex #-} -- share code
lazyByteStringHex :: L.ByteString -> Builder
lazyByteStringHex :: L.LazyByteString -> Builder
lazyByteStringHex = P.primMapLazyByteStringFixed P.word8HexFixed


Expand Down
6 changes: 3 additions & 3 deletions Data/ByteString/Builder/Extra.hs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ import Foreign
-- * an IO action for writing the Builder's data into a user-supplied memory
-- buffer.
--
-- * a pre-existing chunks of data represented by a strict 'S.ByteString'
-- * a pre-existing chunks of data represented by a 'S.StrictByteString'
--
-- While this is rather low level, it provides you with full flexibility in
-- how the data is written out.
Expand Down Expand Up @@ -107,10 +107,10 @@ data Next =

-- | In addition to the data that has just been written into your buffer
-- by the 'BufferWriter' action, it gives you a pre-existing chunk
-- of data as a 'S.ByteString'. It also gives you the following 'BufferWriter'
-- of data as a 'S.StrictByteString'. It also gives you the following 'BufferWriter'
-- action. It is safe to run this following action using a buffer with as
-- much free space as was left by the previous run action.
| Chunk !S.ByteString BufferWriter
| Chunk !S.StrictByteString BufferWriter

-- | Turn a 'Builder' into its initial 'BufferWriter' action.
--
Expand Down
Loading