t$lJ}      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|tested on GHC only experimental Simon Meier <iridcode@gmail.com>A 8 fills a buffer from the given start pointer as long as 4 possible and returns control to the caller using a  , once it is  required. %Pointer to the next free byte in the  buffer. A  must start writing  its data from this address. Pointer to the first byte after the  buffer. A  must never write  data at or after this address. )Signal to the driver about the next step  to be taken. A  signals to the driver of the  execution the next  step to be taken. ModifyChunks pf fbs nextStep) signals that the data written up to the  next free byte pf7 must be output and the remaining lazy bytestring that  is produced by executing nextStep% must be modified using the function  fbs. KThis signal is used to insert bytestrings directly into the output stream. I It can also be used to efficiently hand over control to another library / for generating streams of strict bytestrings. BufferFull newSize pf nextStep% signals that the buffer is full and 0 data has been written up to the next free byte pf. Moreover, the next  build step to be executed nextStep$ requires a buffer of at least size  newSize to execute successfully.  A driver must( guarantee that the buffer used to call nextStep is at  least of size newSize. Done pf signals that the  is finished and data has been " written up to the next free byte pf. GIntuitively, a builder denotes the construction of a lazy bytestring. FBuilders can be created from primitive buffer manipulations using the  Write abstraction provided by in Blaze.ByteString.Builder.Write. However for L many Haskell values, there exist predefined functions doing that already.  For example, UTF-8 encoding } and ~ values is provided by the  functions in "Blaze.ByteString.Builder.Char.Utf8!. Concatenating builders is done  using their  instance. KSemantically, builders are nothing special. They just denote a sequence of K bytes. However, their representation is chosen such that this sequence of B bytes can be efficiently (in terms of CPU cycles) computed in an L incremental, chunk-wise fashion such that the average chunk-size is large. I Note that the large average chunk size allows to make good use of cache K prefetching in later processing steps (e.g. compression) or to reduce the M sytem call overhead when writing the resulting lazy bytestring to a file or  sending it over the network. :For precisely understanding the performance of a specific , H benchmarking is unavoidable. Moreover, it also helps to understand the K implementation of builders and the predefined combinators. This should be J amenable to the average Haskell programmer by reading the source code of  !Blaze.ByteString.Builder.Internal) and the other modules of this library. LThe guiding implementation principle was to reduce the abstraction cost per M output byte. We use continuation passing to achieve a constant time append. M The output buffer is filled by the individual builders as long as possible. M They call each other directly when they are done and control is returned to  the driver (e.g.,  ") only when the buffer is full, a L bytestring needs to be inserted directly, or no more bytes can be written. K We also try to take the pressure off the cache by moving variables as far G out of loops as possible. This leads to some duplication of code, but N results in sometimes dramatic increases in performance. For example, see the   fromWord8s function in Blaze.ByteString.Builder.Word. GDefault size (~32kb) for the buffer that becomes a chunk of the output  stream once it is filled. CThe minimal length (~4kb) a buffer must have before filling it and 1 outputting it as a chunk of the output stream. 6This size determines when a buffer is spilled after a   or a direct K bytestring insertion. It is also the size of the first chunk generated by   . BThe default length (64) for the first buffer to be allocated when  converting a  to a lazy bytestring. See   for further explanation. DThe maximal number of bytes for that copying is cheaper than direct M insertion into the output stream. This takes into account the fragmentation 6 that may occur in the output buffer due to the early   implied by the  direct bytestring insertion.   = 2 *  EOutput all data written in the current buffer and start a new chunk. FThe use uf this function depends on how the resulting bytestrings are  consumed.  ; is possibly not very useful in non-interactive scenarios. D However, it is kept for compatibility with the builder provided by  Data.Binary.Builder.  When using   to extract a lazy  from a  D, this means that a new chunk will be started in the resulting lazy  6. The remaining part of the buffer is spilled, if the G reamining free space is smaller than the minimal desired buffer size. Run a  with the given buffer sizes. &Use this function for integrating the  type with other libraries ! that generate lazy bytestrings. JNote that the builders should guarantee that on average the desired chunk E size is attained. Builders may decide to start a new buffer and not N completely fill the existing buffer, if this is faster. However, they should E not spill too much of the buffer, if they cannot compensate for it. A call 4toLazyByteStringWith bufSize minBufSize firstBufSize will generate K a lazy bytestring according to the following strategy. First, we allocate  a buffer of size  firstBufSize+ and start filling it. If it overflows, we  allocate a buffer of size  minBufSize$ and copy the first buffer to it in N order to avoid generating a too small chunk. Finally, every next buffer will  be of size bufSize5. This, slow startup strategy is required to achieve  good speed for short (<2200 bytes) resulting bytestrings, as for them the L allocation cost is of a large buffer cannot be compensated. Moreover, this E strategy also allows us to avoid spilling too much memory for short  resulting bytestrings. Note that setting firstBufSize >= minBufSize implies that the first buffer G is no longer copied but allocated and filled directly. Hence, setting  firstBufSize = bufSize5 means that all chunks will use an underlying buffer  of size bufSize:. This is recommended, if you know that you always output  more than  minBufSize bytes. 5Buffer size (upper-bounds the resulting chunk size). 1Minimal free buffer space for continuing filling  the same buffer after a   or a direct bytestring 4 insertion. This corresponds to the minimal desired  chunk size. 3Size of the first buffer to be used and copied for  larger resulting sequences Builder to run. /Lazy bytestring to output after the builder is  finished. Resulting lazy bytestring Extract the lazy - from the builder by running it with default A buffer sizes. Use this function, if you do not have any special . considerations with respect to buffer sizes.     b =      b L.empty Note that   is a  homomorphism.  , toLazyByteString mempty == mempty U toLazyByteString (x `mappend` y) == toLazyByteString x `mappend` toLazyByteString y KHowever, in the second equation, the left-hand-side is generally faster to  execute. FPack the chunks of a lazy bytestring into a single strict bytestring. IRun the builder to construct a strict bytestring containing the sequence n of bytes denoted by the builder. This is done by first serializing to a lazy bytestring and then packing its 4 chunks to a appropriately sized strict bytestring.  . toByteString = packChunks . toLazyByteString  Note that   is a  homomorphism.  ( toByteString mempty == mempty I toByteString (x `mappend` y) == toByteString x `mappend` toByteString y KHowever, in the second equation, the left-hand-side is generally faster to  execute. toByteStringIOWith bufSize io b runs the builder b with a buffer of  at least the size bufSize and executes the  action io whenever the  buffer is full.  Compared to  ) this function requires less allocation, A as the output buffer is only allocated once at the start of the N serialization and whenever something bigger than the current buffer size has I to be copied into the buffer, which should happen very seldomly for the N default buffer size of 32kb. Hence, the pressure on the garbage collector is K reduced, which can be an advantage when building long sequences of bytes. Buffer size (upper bounds  the number of bytes forced  per call to the  action).  action to execute per  full buffer, which is  referenced by a strict  .  to run.  Resulting  action. Run the builder with a d buffer and execute the given  5 action whenever the buffer is full or gets flushed.    =   This is a & homomorphism in the following sense. 0 toByteStringIO io mempty == return () Q toByteStringIO io (x `mappend` y) == toByteStringIO io x >> toByteStringIO io y     tested on GHC only experimental Simon Meier <iridcode@gmail.com> A value  Write n io denotes the write of n bytes to a buffer. The % actual write is executed by calling io with a pointer pf to the first E free byte that the write should start with. Note that the caller of io pf  must ensure that n bytes are free starting from pf. For example, the function  writeWord8 provided by  Blaze.ByteString.Builder.Word creates a ! that writes a single fixed byte  to a buffer.   writeWord8 :: Word8 -> Write , writeWord8 x = Write 1 (\pf -> poke pf x) JThe benefit of writes is that they abstract low-level manipulations (e.g.   and 3) of sequences of bytes in a form that that can be * completely optimized away in many cases. For example, the  instance of  allows to formulate writing a " three-tuple of bytes as follows.  5 writeThreeWord8 :: (Word8, Word8, Word8) -> Write  writeThreeWord8 (x,y,z) = @ writeWord8 x `mappend` writeWord8 y `mappend` writeWord8 z MThis expression will be optimized by the compiler to the following efficient  .  1 writeThreeWord8 (x, y, z) = Write 3 $ \pf -> do  poke pf x  poke (pf `plusPtr` 1) y  poke (pf `plusPtr` 2) z  Writes are atomic5. This means that the written data cannot be wrapped L over buffer boundaries as it can be done for builders. For writes it holds M that either the buffer has enough free space and the write can proceed or a L new buffer with a size larger or equal to the number of bytes to write has  to be allocated. Moreover, for a 3, the size of the data to be written must be known L before the data can be written. Hence, if this size is data-dependent, the N control flow becomes complicated: first, all data must be forced and stored, I then the size check happens, and only afterwards the stored data can be D written. Therefore, because of cache misses, composing writes with L data-dependent size computations may actually be slower than combining the B resulting builders. Use benchmarking to make informed decisions.  Create a  from a single write w. For good performance, w must  feature an outermost 0 constructor such that the pattern match can be  eliminated during compilation. Semantically, it holds that  . fromWrite . write = fromWriteSingleton write GHowever, performance-wise the right-hand side is more efficient due to 6 currently unknown reasons. Use the second form, when I defining functions for creating builders from writes of Haskell values. #(Use the standard benchmark in the  blaze-html package when investigating  this phenomenon.)  Create a  constructor from a single  constructor.  Construct a 5 writing a list of data one element at a time from a  abstraction.  Construct a 6 writing a list of data two elements at a time from a   abstraction.  Construct a 7 writing a list of data four elements at a time from a   abstraction.  Construct a 8 writing a list of data eight elements at a time from a   abstraction.  Construct a 5 writing a list of data 16 elements at a time from a   abstraction.   tested on GHC only experimental Simon Meier <iridcode@gmail.com>$Write a single byte. Write a  in big endian format. Write a  in little endian format. Write a  in big endian format. Write a  in little endian format. Write a  in big endian format. Write a  in little endian format. Write a single native machine . The  is written in host order, & host endian form, for the machine you're on. On a 64 bit machine the  K is an 8 byte value, on a 32 bit machine, 4 bytes. Values written this way F are not portable to different endian or word sized machines, without  conversion. !Write a + in native host order and host endianness. "Write a + in native host order and host endianness. #Write a + in native host order and host endianness. $Serialize a single byte. %Serialize a list of bytes. & Serialize a  in big endian format. 'Serialize a list of s in big endian format. ( Serialize a  in little endian format. )Serialize a list of s in little endian format. * Serialize a  in big endian format. +Serialize a list of s in big endian format. , Serialize a  in little endian format. -Serialize a list of s in little endian format. . Serialize a  in big endian format. /Serialize a list of s in big endian format. 0 Serialize a  in little endian format. 1Serialize a list of s in little endian format. 2"Serialize a single native machine . The  is serialized in host - order, host endian form, for the machine you're on. On a 64 bit machine the  G is an 8 byte value, on a 32 bit machine, 4 bytes. Values written this J way are not portable to different endian or word sized machines, without  conversion. 3Serialize a list of s.  See 2 for usage considerations. 4Write a + in native host order and host endianness. 5Write a list of ,s in native host order and host endianness. 6Write a + in native host order and host endianness. 7Write a list of ,s in native host order and host endianness. 8Write a + in native host order and host endianness. 9Write a list of ,s in native host order and host endianness. ! !"#$%&'()*+,-./0123456789! !"#$%&*.+'/(,0)-124683579! !"#$%&'()*+,-./0123456789tested on GHC only experimental Simon Meier <iridcode@gmail.com>!:Write a single signed byte. ; Write an  in big endian format. < Write an  in little endian format. = Write an  in big endian format. > Write an  in little endian format. ? Write an  in big endian format. @ Write an  in little endian format. AWrite a single native machine . The  is written in host order, & host endian form, for the machine you're on. On a 64 bit machine the  K is an 8 byte value, on a 32 bit machine, 4 bytes. Values written this way I are not portable to different endian or integer sized machines, without  conversion. B Write an + in native host order and host endianness. C Write an + in native host order and host endianness. D Write an + in native host order and host endianness. ESerialize a single byte. FSerialize a list of bytes. G Serialize an  in big endian format. HSerialize a list of s in big endian format. I Serialize an  in little endian format. JSerialize a list of s in little endian format. K Serialize an  in big endian format. LSerialize a list of s in big endian format. M Serialize an  in little endian format. NSerialize a list of s in little endian format. O Serialize an  in big endian format. PSerialize a list of s in big endian format. Q Serialize an  in little endian format. RSerialize a list of s in little endian format. S"Serialize a single native machine . The  is serialized in host - order, host endian form, for the machine you're on. On a 64 bit machine the  G is an 8 byte value, on a 32 bit machine, 4 bytes. Values written this M way are not portable to different endian or integer sized machines, without  conversion. TSerialize a list of s.  See S for usage considerations. U Write an + in native host order and host endianness. VWrite a list of ,s in native host order and host endianness. W Write an + in native host order and host endianness. XWrite a list of ,s in native host order and host endianness. Y Write an + in native host order and host endianness. ZWrite a list of ,s in native host order and host endianness. !:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ!:;=?<>@ABCDEFGKOLHPIMQJNRSUWYTVXZ!:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZtested on GHC only experimental Simon Meier <iridcode@gmail.com> [Write a strict  to a buffer. \,Smart serialization of a strict bytestring.  \ = ]  DUse this function to serialize strict bytestrings. It guarantees an L average chunk size of 4kb, which has been shown to be a reasonable size in J benchmarks. Note that the check whether to copy or to insert is (almost) 9 free as the builder performance is mostly memory-bound. JIf you statically know that copying or inserting the strict bytestring is . always the best choice, then you can use the ^ or  _ functions. ]%fromByteStringWith maximalCopySize bs" serializes the strict bytestring  bs# according to the following rules.   S.length bs <= maximalCopySize: bs! is copied to the output buffer. S.length bs > maximalCopySize: bs" the output buffer is flushed and  bs> is inserted directly as separate chunk in the output stream. IThese rules guarantee that average chunk size in the output stream is at  least half the maximalCopySize. !Maximal number of bytes to copy. Strict  to serialize.  Resulting . ^copyByteString bs! serialize the strict bytestring bs by copying it to  the output buffer. LUse this function to serialize strict bytestrings that are statically known  to be smallish (<= 4kb). _insertByteString bs" serializes the strict bytestring bs by inserting / it directly as a chunk of the output stream. LNote that this implies flushing the output buffer; even if it contains just E a single byte. Hence, you should use this operation only for large (> 8kb) M bytestrings, as otherwise the resulting output stream may be too fragmented  to be processed efficiently. `O(n),. Smart serialization of a lazy bytestring.  ` = a  JUse this function to serialize lazy bytestrings. It guarantees an average D chunk size of 4kb, which has been shown to be a reasonable size in J benchmarks. Note that the check whether to copy or to insert is (almost) 9 free as the builder performance is mostly memory-bound. 1If you statically know that copying or inserting all chunks of the lazy < bytestring is always the best choice, then you can use the  b or c functions. aO(n)E. Serialize a lazy bytestring chunk-wise according to the same rules  as in ]. Semantically, it holds that  & fromLazyByteStringWith maxCopySize ? = mconcat . map (fromByteStringWith maxCopySize) . L.toChunks DHowever, the left-hand-side is much more efficient, as it moves the L end-of-buffer pointer out of the inner loop and provides the compiler with  more strictness information. !Maximal number of bytes to copy. Lazy  to serialize.  Resulting . bO(n)). Serialize a lazy bytestring by copying all chunks sequentially  to the output buffer. See ^ for usage considerations. cO(n)+. Serialize a lazy bytestring by inserting all its chunks directly  into the output stream. See _ for usage considerations.  For library developers, see the  build signal, if you  need an O(1)3 lazy bytestring insert based on difference lists. [\]^_`abc [\]^_`abc [\]^_`abctested on GHC only experimental Simon Meier <iridcode@gmail.com>d5Write a UTF-8 encoded Unicode character to a buffer. Note that the control flow of d" is more complicated than the one  of  writeWord8*, as the size of the write depends on the } written.  Therefore,  / fromWrite $ writeChar a `mappend` writeChar b must not always be faster than  ! fromChar a `mappend` fromChar b -Use benchmarking to make informed decisions. KEncode a Unicode character to another datatype, using UTF-8. This function J acts as an abstract way of encoding characters, as it is unaware of what L needs to happen with the resulting bytes: you have to specify functions to  deal with those.  1-byte UTF-8  2-byte UTF-8  3-byte UTF-8  4-byte UTF-8 Input } Result eO(1):. Serialize a Unicode character using the UTF-8 encoding. fO(n). Serialize a Unicode ~ using the UTF-8 encoding. gO(n). Serialize a value by (ing it and UTF-8 encoding the resulting  ~. hO(n). Serialize a strict Unicode ! value using the UTF-8 encoding. 1Note that this function is currently faster than  provided by  Data.Text.Encoding . Moreover, h is also lazy, while  TL.encodeUtf8  is strict. iO(n). Serialize a lazy Unicode ! value using the UTF-8 encoding. 1Note that this function is currently faster than  TL.encodeUtf8 provided by  Data.Text.Lazy.Encoding. defghidefghidefghitested on GHC only experimental Simon Meier <iridcode@gmail.com> jO(1). An empty builder.  Deprecated: use  instead. kO(1). Append two builders.  Deprecated: use  instead. lO(1). Serialize a single byte.  Deprecated: use $ instead. mO(1). Serialize a  in big endian format.  Deprecated: use & instead. nO(1). Serialize a  in big endian format.  Deprecated: use * instead. oO(1). Serialize a  in big endian format.  Deprecated: use . instead. pO(1). Serialize a  in little endian format.  Deprecated: use ( instead. qO(1). Serialize a  in little endian format.  Deprecated: use , instead. rO(1). Serialize a  in little endian format.  Deprecated: use 0 instead. sO(1). Serialize a  in host endian format.  Deprecated: use 2 instead. tO(1). Serialize a  in host endian format.  Deprecated: use 4 instead. uO(1). Serialize a  in host endian format.  Deprecated: use 6 instead. vO(1). Serialize a  in host endian format.  Deprecated: use 8 instead. h  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcjklmnopqrstuv jlkmnopqrstuv jklmnopqrstuvtested on GHC only experimental Simon Meier <iridcode@gmail.com>wGWrite a HTML escaped and UTF-8 encoded Unicode character to a bufffer. xO(1).< Serialize a HTML escaped Unicode character using the UTF-8  encoding. yO(n)#. Serialize a HTML escaped Unicode ~ using the UTF-8  encoding. zO(n). Serialize a value by #ing it and then, HTML escaping and  UTF-8 encoding the resulting ~. {O(n)*. Serialize a HTML escaped strict Unicode  value using the  UTF-8 encoding. |O(n)#. Serialize a HTML escaped Unicode  using the UTF-8 encoding. defghiwxyz{|wxyz{|wxyz{|      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~blaze-builder-0.2.0.0!Blaze.ByteString.Builder.InternalBlaze.ByteString.Builder.WriteBlaze.ByteString.Builder.WordBlaze.ByteString.Builder.Int#Blaze.ByteString.Builder.ByteString"Blaze.ByteString.Builder.Char.Utf8Blaze.ByteString.Builder"Blaze.ByteString.Builder.Html.Utf8 BuildStep BuildSignal ModifyChunks BufferFullDoneBuilderdefaultBufferSizedefaultMinimalBufferSizedefaultMaximalCopySizeflushtoLazyByteStringWithtoLazyByteString toByteStringtoByteStringIOWithtoByteStringIOWrite fromWritefromWriteSingletonfromWrite1ListfromWrite2ListfromWrite4ListfromWrite8ListfromWrite16List writeWord8 writeWord16be writeWord16le writeWord32be writeWord32le writeWord64be writeWord64le writeWordhostwriteWord16hostwriteWord32hostwriteWord64host fromWord8 fromWord8s fromWord16be fromWord16sbe fromWord16le fromWord16sle fromWord32be fromWord32sbe fromWord32le fromWord32sle fromWord64be fromWord64sbe fromWord64le fromWord64sle fromWordhost fromWordshostfromWord16hostfromWord16shostfromWord32hostfromWord32shostfromWord64hostfromWord64shost writeInt8 writeInt16be writeInt16le writeInt32be writeInt32le writeInt64be writeInt64le writeInthostwriteInt16hostwriteInt32hostwriteInt64hostfromInt8 fromInt8s fromInt16be fromInt16sbe fromInt16le fromInt16sle fromInt32be fromInt32sbe fromInt32le fromInt32sle fromInt64be fromInt64sbe fromInt64le fromInt64sle fromInthost fromIntshost fromInt16hostfromInt16shost fromInt32hostfromInt32shost fromInt64hostfromInt64shostwriteByteStringfromByteStringfromByteStringWithcopyByteStringinsertByteStringfromLazyByteStringfromLazyByteStringWithcopyLazyByteStringinsertLazyByteString writeCharfromChar fromStringfromShowfromText fromLazyTextemptyappend singleton putWord16be putWord32be putWord64be putWord16le putWord32le putWord64le putWordhost putWord16host putWord32host putWord64hostwriteHtmlEscapedCharfromHtmlEscapedCharfromHtmlEscapedStringfromHtmlEscapedShowfromHtmlEscapedTextfromHtmlEscapedLazyTextghc-prim GHC.TypesCharbaseGHC.BaseString Data.MonoidMonoiddefaultFirstBufferSizebytestring-0.9.1.7Data.ByteString.Lazy.Internal ByteString packChunksIOData.ByteString.InternalForeign.StorablepokeForeign.Marshal.Utils copyBytesGHC.WordWord16Word32Word64Word shiftr_w16 shiftr_w32 shiftr_w64GHC.IntInt16Int32Int64IntencodeCharUtf8GHC.ShowShow text-0.10.0.0Data.Text.InternalTextData.Text.Encoding encodeUtf8Data.Text.Lazy.EncodingData.Text.Lazy.Internalmemptymappend