Prim +Data.ByteString.Builder

module Data.ByteString.Builder.Prim
bytestring Data.ByteString.Builder.Prim
This module provides Builder primitives, which are lower level building blocks for constructing Builders. You don't need to go down to this level but it can be slightly faster. Morally, builder primitives are like functions a -> Builder, that is they take a value and encode it as a sequence of bytes, represented as a Builder. Of course their implementation is a bit more specialised. Builder primitives come in two forms: fixed-size and bounded-size. * Fixed(-size) primitives are builder primitives that always result in a sequence of bytes of a fixed length. That is, the length is independent of the value that is encoded. An example of a fixed size primitive is the big-endian encoding of a Word64, which always results in exactly 8 bytes. * Bounded(-size) primitives are builder primitives that always result in a sequence of bytes that is no larger than a predetermined bound. That is, the bound is independent of the value that is encoded but the actual length will depend on the value. An example for a bounded primitive is the UTF-8 encoding of a Char, which can be 1,2,3 or 4 bytes long, so the bound is 4 bytes. Note that fixed primitives can be considered as a special case of bounded primitives, and we can lift from fixed to bounded. Because bounded primitives are the more general case, in this documentation we only refer to fixed size primitives that the resulting sequence of bytes is of a fixed length. Otherwise, we just refer to bounded size primitives. The purpose of using builder primitives is to improve the performance of Builders. These improvements stem from making the two most common steps performed by a Builder more efficient. We explain these two steps in turn. The first most common step is the concatenation of two Builders. Internally, concatenation corresponds to function composition. (Note that Builders can be seen as difference-lists of buffer-filling functions; cf. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/dlist. ) Function composition is a fast O(1) operation. However, we can use bounded primitives to remove some of these function compositions altogether, which is more efficient. The second most common step performed by a Builder is to fill a buffer using a bounded primitives, which works as follows. The Builder checks whether there is enough space left to execute the bounded primitive. If there is, then the Builder executes the bounded primitive and calls the next Builder with the updated buffer. Otherwise, the Builder signals its driver that it requires a new buffer. This buffer must be at least as large as the bound of the primitive. We can use bounded primitives to reduce the number of buffer-free checks by fusing the buffer-free checks of consecutive Builders. We can also use bounded primitives to simplify the control flow for signalling that a buffer is full by ensuring that we check first that there is enough space left and only then decide on how to encode a given value. Let us illustrate these improvements on the CSV-table rendering example from Data.ByteString.Builder. Its "hot code" is the rendering of a table's cells, which we implement as follows using only the functions from the Builder API. > import Data.ByteString.Builder as B > > renderCell :: Cell -> Builder > renderCell (StringC cs) = renderString cs > renderCell (IntC i) = B.intDec i > > renderString :: String -> Builder > renderString cs = B.charUtf8 '"' <> foldMap escape cs <> B.charUtf8 '"' > > escape '\\' = B.charUtf8 '\\' <> B.charUtf8 '\\' > escape '\"' = B.charUtf8 '\\' <> B.charUtf8 '\"' > escape c = B.charUtf8 c Efficient encoding of Ints as decimal numbers is performed by intDec. Optimization potential exists for the escaping of Strings. The above implementation has two optimization opportunities. First, the buffer-free checks of the Builders for escaping double quotes and backslashes can be fused. Second, the concatenations performed by foldMap can be eliminated. The following implementation exploits these optimizations. > import qualified Data.ByteString.Builder.Prim as P > import Data.ByteString.Builder.Prim > ( condB, liftFixedToBounded, (>*<), (>$<) ) > > renderString :: String -> Builder > renderString cs = > B.charUtf8 '"' <> E.encodeListWithB escape cs <> B.charUtf8 '"' > > escape :: E.BoundedPrim Char > escape = > condB (== '\\') (fixed2 ('\\', '\\')) $ > condB (== '\"') (fixed2 ('\\', '\"')) $ > E.charUtf8 > > {-# INLINE fixed2 #-} > fixed2 x = liftFixedToBounded $ const x >$< E.char7 >*< E.char7 The code should be mostly self-explanatory. The slightly awkward syntax is because the combinators are written such that the size-bound of the resulting BoundedPrim can be computed at compile time. We also explicitly inline the fixed2 primitive, which encodes a fixed tuple of characters, to ensure that the bound computation happens at compile time. When encoding the following list of Strings, the optimized implementation of renderString is two times faster. > maxiStrings :: [String] > maxiStrings = take 1000 $ cycle ["hello", "\"1\"", "»-wörld"] Most of the performance gain stems from using primMapListBounded, which encodes a list of values from left-to-right with a BoundedPrim. It exploits the Builder internals to avoid unnecessary function compositions (i.e., concatenations). In the future, we might expect the compiler to perform the optimizations implemented in primMapListBounded. However, it seems that the code is currently to complicated for the compiler to see through. Therefore, we provide the BoundedPrim escape hatch, which allows data structures to provide very efficient encoding traversals, like primMapListBounded for lists. Note that BoundedPrims are a bit verbose, but quite versatile. Here is an example of a BoundedPrim for combined HTML escaping and UTF-8 encoding. It exploits that the escaped character with the maximal Unicode codepoint is '>'. > {-# INLINE charUtf8HtmlEscaped #-} > charUtf8HtmlEscaped :: E.BoundedPrim Char > charUtf8HtmlEscaped = > condB (> '>' ) E.charUtf8 $ > condB (== '<' ) (fixed4 ('&',('l',('t',';')))) $ -- &lt; > condB (== '>' ) (fixed4 ('&',('g',('t',';')))) $ -- &gt; > condB (== '&' ) (fixed5 ('&',('a',('m',('p',';'))))) $ -- &amp; > condB (== '"' ) (fixed5 ('&',('#',('3',('4',';'))))) $ -- &#34; > condB (== '\'') (fixed5 ('&',('#',('3',('9',';'))))) $ -- &#39; > (liftFixedToBounded E.char7) -- fallback for Chars smaller than '>' > > {-# INLINE fixed4 #-} > fixed4 x = liftFixedToBounded $ const x >$< > E.char7 >*< E.char7 >*< E.char7 >*< E.char7 > > {-# INLINE fixed5 #-} > fixed5 x = liftFixedToBounded $ const x >$< > E.char7 >*< E.char7 >*< E.char7 >*< E.char7 >*< E.char7 This module currently does not expose functions that require the special properties of fixed-size primitives. They are useful for prefixing Builders with their size or for implementing chunked encodings. We will expose the corresponding functions in future releases of this library.
package PrimitiveArray
package
This library provides efficient multidimensional arrays. In general all operations are (highly) unsafe, no bounds-checking or other sanity-checking is performed. Operations are aimed toward efficiency as much as possible. Version 0.5.2.0
package prim-uniq
package
Opaque unique identifiers in primitive state monads and a GADT-like type using them as witnesses of type equality. Version 0.1.0.1
primBounded :: BoundedPrim a -> (a -> Builder)
bytestring Data.ByteString.Builder.Prim
Create a Builder that encodes values with the given BoundedPrim. We rewrite consecutive uses of primBounded such that the bound-checks are fused. For example, > primBounded (word32 c1) `mappend` primBounded (word32 c2) is rewritten such that the resulting Builder checks only once, if ther are at 8 free bytes, instead of checking twice, if there are 4 free bytes. This optimization is not observationally equivalent in a strict sense, as it influences the boundaries of the generated chunks. However, for a user of this library it is observationally equivalent, as chunk boundaries of a lazy ByteString can only be observed through the internal interface. Morevoer, we expect that all primitives write much fewer than 4kb (the default short buffer size). Hence, it is safe to ignore the additional memory spilled due to the more agressive buffer wrapping introduced by this optimization.
package primes
package
This Haskell library provides an efficient lazy wheel sieve for prime generation inspired by Lazy wheel sieves and spirals of primes by Colin Runciman and The Genuine Sieve of Eratosthenes by Melissa O'Neil. Version 0.2.1.0
primFixed :: FixedPrim a -> (a -> Builder)
bytestring Data.ByteString.Builder.Prim
Encode a value with a FixedPrim.
package primitive
package
This package provides various primitive memory-related operations. Changes in version 0.5.0.1 * Disable array copying primitives for GHC 7.6.* and earlier Changes in version 0.5 * New in Data.Primitive.MutVar: atomicModifyMutVar * Efficient block fill operations: setByteArray, setAddr Version 0.5.1.0
primMapByteStringBounded :: BoundedPrim Word8 -> ByteString -> Builder
bytestring Data.ByteString.Builder.Prim
Create a Builder that encodes each Word8 of a strict ByteString using a BoundedPrim. For example, we can write a Builder that filters a strict ByteString as follows. > import Data.ByteString.Builder.Primas P (word8, condB, emptyB) > filterBS p = P.condB p P.word8 P.emptyB
primMapByteStringFixed :: FixedPrim Word8 -> (ByteString -> Builder)
bytestring Data.ByteString.Builder.Prim
Heavy inlining. Encode all bytes of a strict ByteString from left-to-right with a FixedPrim. This function is quite versatile. For example, we can use it to construct a Builder that maps every byte before copying it to the buffer to be filled. > mapToBuilder :: (Word8 -> Word8) -> S.ByteString -> Builder > mapToBuilder f = encodeByteStringWithF (contramapF f word8) We can also use it to hex-encode a strict ByteString as shown by the byteStringHex example above.
primMapLazyByteStringBounded :: BoundedPrim Word8 -> ByteString -> Builder
bytestring Data.ByteString.Builder.Prim
Chunk-wise application of primMapByteStringBounded.
primMapLazyByteStringFixed :: FixedPrim Word8 -> (ByteString -> Builder)
bytestring Data.ByteString.Builder.Prim
Heavy inlining. Encode all bytes of a lazy ByteString from left-to-right with a FixedPrim.
primMapListBounded :: BoundedPrim a -> [a] -> Builder
bytestring Data.ByteString.Builder.Prim
Create a Builder that encodes a list of values consecutively using a BoundedPrim for each element. This function is more efficient than the canonical > filter p = > B.toLazyByteString . > E.encodeLazyByteStringWithF (E.ifF p E.word8) E.emptyF) > mconcat . map (primBounded w) or > foldMap (primBounded w) because it moves several variables out of the inner loop.
primMapListFixed :: FixedPrim a -> ([a] -> Builder)
bytestring Data.ByteString.Builder.Prim
Encode a list of values from left-to-right with a FixedPrim.
package primula-board
package
Simple ImageBoard like wakaba on Happstack and HSP. Messages on board sended via jabber-bot (primula-bot package). Settings stored in ~/.primularc file. Version 0.0.1
package primula-bot
package
Jabber-bot for communication with primula-board. Settings stored in ~/.primularc file. Version 0.0.2
primUnfoldrBounded :: BoundedPrim b -> (a -> Maybe (b, a)) -> a -> Builder
bytestring Data.ByteString.Builder.Prim
Create a Builder that encodes a sequence generated from a seed value using a BoundedPrim for each sequence element.
primUnfoldrFixed :: FixedPrim b -> (a -> Maybe (b, a)) -> a -> Builder
bytestring Data.ByteString.Builder.Prim
Encode a list of values represented as an unfoldr with a FixedPrim.
package atomic-primops
package
After GHC 7.4 a new `casMutVar#` primop became available, but it's difficult to use safely, because pointer equality is a highly unstable property in Haskell.  This library provides a safer method based on the concept of Tickets. Also, this library uses the &quot;foreign primop&quot; capability of GHC to add access to other variants that may be of interest, specifically, compare and swap inside an array. Changes in 0.3: * Major internal change.  Duplicate the barrier code from the GHC RTS and thus enable support for executables that are NOT built with '-threaded'. Changes in 0.4: * Further internal changes, duplicate cas routine well as barriers. * Add `fetchAddByteArrayInt` * Add an `Unboxed` counter variant that uses movable ByteArrays on the GHC heap. Version 0.4
data BoundedPrim a
bytestring Data.ByteString.Builder.Prim
A builder primitive that always results in sequence of bytes that is no longer than a pre-determined bound.
package dph-prim-interface
package
Empty implementation of flat parallel arrays. This package exists only so that dph-prim-par and dph-prim-seq can provide the same interface. Version 0.7.0.1

Show more results