{-# LANGUAGE OverloadedStrings #-} -- | -- Module : BlazeVsBinary -- Copyright : (c) 2010 Jasper Van der Jeught & Simon Meier -- License : BSD3-style (see LICENSE) -- -- Maintainer : Simon Meier -- Stability : experimental -- Portability : tested on GHC only -- -- A comparison between 'blaze-builder' and the Data.Binary.Builder from -- 'binary'. The goal is to measure the performance on serializing dynamic -- data referenced by a list. -- -- Note that some of the benchmarks are a bit unfair with respect to -- blaze-builder, as it does more than 'binary': -- -- 1. It encodes chars as utf-8 strings and does not just truncate character -- value to one byte. -- -- 2. It copies the contents of the lazy bytestring chunks if they are -- shorter than 4kb. This ensures efficient processing of the resulting -- lazy bytestring. 'binary' just inserts the chunks directly in the -- resulting output stream. -- module BlazeVsBinary where import Data.Char (ord) import Data.Monoid (mconcat) import Data.Word (Word8) import qualified Data.Binary.Builder as Binary import Criterion.Main import qualified Data.ByteString.Lazy as L import qualified Data.ByteString as S import Data.Text (Text) import Data.Text.Encoding (encodeUtf8) import qualified Blaze.ByteString.Builder as Blaze import qualified Blaze.ByteString.Builder.Char.Utf8 as Blaze main :: IO () main = defaultMain $ concat [ benchmark "[String]" (mconcat . map (mconcat . (map $ Binary.singleton . fromIntegral . ord))) (mconcat . map Blaze.fromString) strings , benchmark "L.ByteString" (Binary.fromLazyByteString) (Blaze.fromLazyByteString) byteStrings , benchmark "[Text]" (mconcat . map (Binary.fromByteString . encodeUtf8)) (mconcat . map Blaze.fromText) texts , benchmark "[Word8]" (mconcat . map Binary.singleton) (Blaze.fromWord8s) word8s ] where benchmark name binaryF blazeF x = [ bench (name ++ " (Data.Binary builder)") $ whnf (L.length . Binary.toLazyByteString . binaryF) x , bench (name ++ " (blaze builder)") $ whnf (L.length . Blaze.toLazyByteString . blazeF) x ] strings :: [String] strings = replicate 10000 "" {-# NOINLINE strings #-} byteStrings :: L.ByteString byteStrings = L.fromChunks $ replicate 10000 "" {-# NOINLINE byteStrings #-} texts :: [Text] texts = replicate 10000 "" {-# NOINLINE texts #-} word8s :: [Word8] word8s = replicate 10000 $ fromIntegral $ ord 'a' {-# NOINLINE word8s #-}