File: ChunkedWrite.hs

package info (click to toggle)
haskell-blaze-builder 0.4.4.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 476 kB
  • sloc: haskell: 5,891; makefile: 87; ansic: 39
file content (157 lines) | stat: -rw-r--r-- 5,638 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module      : ChunkedWrite
-- Copyright   : (c) 2010 Simon Meier
-- License     : BSD3-style (see LICENSE)
--
-- Maintainer  : https://github.com/blaze-builder
-- Stability   : stable
-- Portability : tested on GHC only
--
-- Test different strategies for writing lists of simple values:
--
--  1. Using 'mconcat . map from<Value>'
--
--  2. Using the specialized 'fromWrite<n>List' function where 'n' denotes
--     the number of elements to write at the same time. Writing chunks of
--     elements reduces the overhead from the buffer overflow test that has
--     to be done before every write.
--
module ChunkedWrite where

import Data.Char (chr)
import Data.Int (Int64)
import Data.Word (Word8, Word32)
import Data.Monoid

import Criterion.Main
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString as S

import qualified Blaze.ByteString.Builder           as BB
import qualified Blaze.ByteString.Builder.Char.Utf8 as BB

main :: IO ()
main = defaultMain
    [ bench "S.pack: [Word8] -> S.ByteString" $
        whnf (S.pack) word8s

    , bench "toByteString . fromWord8s: [Word8] -> Builder -> S.ByteString" $
        whnf (BB.toByteString . BB.fromWord8s) word8s

    , bench "L.pack: [Word8] -> L.ByteString" $
        whnf (L.length . L.pack) word8s

    , bench "mconcat . map fromByte: [Word8] -> Builder -> L.ByteString" $
        whnf benchMConcatWord8s word8s
    , bench "fromWrite1List: [Word8] -> Builder -> L.ByteString" $
        whnf bench1Word8s word8s
    , bench "fromWrite2List: [Word8] -> Builder -> L.ByteString" $
        whnf bench2Word8s word8s
    , bench "fromWrite4List: [Word8] -> Builder -> L.ByteString" $
        whnf bench4Word8s word8s
    , bench "fromWrite8List: [Word8] -> Builder -> L.ByteString" $
        whnf bench8Word8s word8s
    , bench "fromWrite16List: [Word8] -> Builder -> L.ByteString" $
        whnf bench16Word8s word8s

    , bench "mconcat . map fromByte: [Char] -> Builder -> L.ByteString" $
        whnf benchMConcatChars chars
    , bench "fromWrite1List: [Char] -> Builder -> L.ByteString" $
        whnf bench1Chars chars
    , bench "fromWrite2List: [Char] -> Builder -> L.ByteString" $
        whnf bench2Chars chars
    , bench "fromWrite4List: [Char] -> Builder -> L.ByteString" $
        whnf bench4Chars chars
    , bench "fromWrite8List: [Char] -> Builder -> L.ByteString" $
        whnf bench8Chars chars
    , bench "fromWrite16List: [Char] -> Builder -> L.ByteString" $
        whnf bench16Chars chars

    , bench "mconcat . map fromWord32host: [Word32] -> Builder -> L.ByteString" $
        whnf benchMConcatWord32s word32s
    , bench "fromWrite1List: [Word32] -> Builder -> L.ByteString" $
        whnf bench1Word32s word32s
    , bench "fromWrite2List: [Word32] -> Builder -> L.ByteString" $
        whnf bench2Word32s word32s
    , bench "fromWrite4List: [Word32] -> Builder -> L.ByteString" $
        whnf bench4Word32s word32s
    , bench "fromWrite8List: [Word32] -> Builder -> L.ByteString" $
        whnf bench8Word32s word32s
    , bench "fromWrite16List: [Word32] -> Builder -> L.ByteString" $
        whnf bench16Word32s word32s
    ]
  where
    n = 100000

    word8s :: [Word8]
    word8s = take n $ map fromIntegral $ [(1::Int)..]
    {-# NOINLINE word8s #-}

    word32s :: [Word32]
    word32s = take n $ [1..]
    {-# NOINLINE word32s #-}

    chars :: String
    chars = take n $ map (chr . fromIntegral) $ word8s
    {-# NOINLINE chars #-}

-- Char

benchMConcatChars :: [Char] -> Int64
benchMConcatChars = L.length . BB.toLazyByteString . mconcat . map BB.fromChar

bench1Chars :: [Char] -> Int64
bench1Chars = L.length . BB.toLazyByteString . BB.fromWrite1List BB.writeChar

bench2Chars :: [Char] -> Int64
bench2Chars = L.length . BB.toLazyByteString . BB.fromWrite2List BB.writeChar

bench4Chars :: [Char] -> Int64
bench4Chars = L.length . BB.toLazyByteString . BB.fromWrite4List BB.writeChar

bench8Chars :: [Char] -> Int64
bench8Chars = L.length . BB.toLazyByteString . BB.fromWrite8List BB.writeChar

bench16Chars :: [Char] -> Int64
bench16Chars = L.length . BB.toLazyByteString . BB.fromWrite16List BB.writeChar

-- Word8

benchMConcatWord8s :: [Word8] -> Int64
benchMConcatWord8s = L.length . BB.toLazyByteString . mconcat . map BB.fromWord8

bench1Word8s :: [Word8] -> Int64
bench1Word8s = L.length . BB.toLazyByteString . BB.fromWrite1List BB.writeWord8

bench2Word8s :: [Word8] -> Int64
bench2Word8s = L.length . BB.toLazyByteString . BB.fromWrite2List BB.writeWord8

bench4Word8s :: [Word8] -> Int64
bench4Word8s = L.length . BB.toLazyByteString . BB.fromWrite4List BB.writeWord8

bench8Word8s :: [Word8] -> Int64
bench8Word8s = L.length . BB.toLazyByteString . BB.fromWrite8List BB.writeWord8

bench16Word8s :: [Word8] -> Int64
bench16Word8s = L.length . BB.toLazyByteString . BB.fromWrite16List BB.writeWord8

-- Word32

benchMConcatWord32s :: [Word32] -> Int64
benchMConcatWord32s = L.length . BB.toLazyByteString . mconcat . map BB.fromWord32host

bench1Word32s :: [Word32] -> Int64
bench1Word32s = L.length . BB.toLazyByteString . BB.fromWrite1List BB.writeWord32host

bench2Word32s :: [Word32] -> Int64
bench2Word32s = L.length . BB.toLazyByteString . BB.fromWrite2List BB.writeWord32host

bench4Word32s :: [Word32] -> Int64
bench4Word32s = L.length . BB.toLazyByteString . BB.fromWrite4List BB.writeWord32host

bench8Word32s :: [Word32] -> Int64
bench8Word32s = L.length . BB.toLazyByteString . BB.fromWrite8List BB.writeWord32host

bench16Word32s :: [Word32] -> Int64
bench16Word32s = L.length . BB.toLazyByteString . BB.fromWrite16List BB.writeWord32host