3-- Copyright : (c) 2019 Harendra Kumar
6-- Maintainer : streamly@composewell.com
10import Control.DeepSeq (NFData)
11import System.IO (openFile, IOMode(..), Handle, hClose)
12import System.Process.Typed (shell, runProcess_)
17import qualified Streamly.Benchmark.FileIO.Stream as BFS
18import qualified Streamly.Benchmark.FileIO.Array as BFA
20-- Input and output file handles
21data Handles = Handles Handle Handle
24scratchDir = "benchmark/scratch/"
27outfile = scratchDir ++ "out.txt"
29blockSize, blockCount :: Int
34-- This is a 500MB text file for text processing benchmarks. We cannot
35-- have it in the repo, therefore we use it locally with DEVBUILD
36-- conditional (enabled by "dev" cabal flag). Some tests that depend on
37-- this file are available only in DEVBUILD mode.
39infile = "benchmark/text-processing/gutenberg-500.txt"
42fileSize = blockSize * blockCount
46infile = scratchDir ++ "in-100MB.txt"
52 -- XXX will this work on windows/msys?
53 let cmd = "mkdir -p " ++ scratchDir
54 ++ "; test -e " ++ infile
55 ++ " || { echo \"creating input file " ++ infile
56 ++ "\" && dd if=/dev/random of=" ++ infile
57 ++ " bs=" ++ show blockSize
58 ++ " count=" ++ show blockCount
61 runProcess_ (shell cmd)
63 inHandle <- openFile infile ReadMode
64 outHandle <- openFile outfile WriteMode
65 href <- newIORef $ Handles inHandle outHandle
66 devNull <- openFile "/dev/null" WriteMode
70 [ mkBench "last" href $ do
71 Handles inh _ <- readIORef href
73 -- Note: this cannot be fairly compared with GNU wc -c or wc -m as
74 -- wc uses lseek to just determine the file size rather than reading
75 -- and counting characters.
76 , mkBench "length (bytecount)" href $ do
77 Handles inh _ <- readIORef href
79 , mkBench "linecount" href $ do
80 Handles inh _ <- readIORef href
82 , mkBench "wordcount" href $ do
83 Handles inh _ <- readIORef href
85 , mkBench "sum" href $ do
86 Handles inh _ <- readIORef href
88 , mkBench "cat" href $ do
89 Handles inh _ <- readIORef href
91 , mkBench "catBracket" href $ do
92 Handles inh _ <- readIORef href
93 BFA.catBracket devNull inh
94 , mkBench "catBracketIO" href $ do
95 Handles inh _ <- readIORef href
96 BFA.catBracketIO devNull inh
97 , mkBench "catBracketStream" href $ do
98 Handles inh _ <- readIORef href
99 BFA.catBracketStream devNull inh
100 , mkBench "catBracketStreamIO" href $ do
101 Handles inh _ <- readIORef href
102 BFA.catBracketStreamIO devNull inh
103 , mkBench "catOnException" href $ do
104 Handles inh _ <- readIORef href
105 BFA.catOnException devNull inh
106 , mkBench "read-utf8" href $ do
107 Handles inh _ <- readIORef href
108 BFA.decodeUtf8Lenient inh
110 , bgroup "readStream"
111 [ mkBench "last" href $ do
112 Handles inh _ <- readIORef href
114 , mkBench "length (bytecount)" href $ do
115 Handles inh _ <- readIORef href
117 , mkBench "linecount" href $ do
118 Handles inh _ <- readIORef href
120 , mkBench "linecountU" href $ do
121 Handles inh _ <- readIORef href
123 , mkBench "wordcount" href $ do
124 Handles inh _ <- readIORef href
126 , mkBench "sum" href $ do
127 Handles inh _ <- readIORef href
129 , mkBench "cat" href $ do
130 Handles inh _ <- readIORef href
132 , mkBench "catStream" href $ do
133 Handles inh _ <- readIORef href
134 BFS.catStreamWrite devNull inh
136 , mkBench "catOnException" href $ do
137 Handles inh _ <- readIORef href
138 BFS.catOnException devNull inh
139 , mkBench "catOnExceptionStream" href $ do
140 Handles inh _ <- readIORef href
141 BFS.catOnExceptionStream devNull inh
142 , mkBench "catHandle" href $ do
143 Handles inh _ <- readIORef href
144 BFS.catHandle devNull inh
145 , mkBench "catHandleStream" href $ do
146 Handles inh _ <- readIORef href
147 BFS.catHandleStream devNull inh
148 , mkBench "catFinally" href $ do
149 Handles inh _ <- readIORef href
150 BFS.catFinally devNull inh
151 , mkBench "catFinallyIO" href $ do
152 Handles inh _ <- readIORef href
153 BFS.catFinallyIO devNull inh
154 , mkBench "catFinallyStream" href $ do
155 Handles inh _ <- readIORef href
156 BFS.catFinallyStream devNull inh
157 , mkBench "catFinallyStreamIO" href $ do
158 Handles inh _ <- readIORef href
159 BFS.catFinallyStreamIO devNull inh
160 , mkBench "catBracketStream" href $ do
161 Handles inh _ <- readIORef href
162 BFS.catBracketStream devNull inh
163 , mkBench "catBracketStreamIO" href $ do
164 Handles inh _ <- readIORef href
165 BFS.catBracketStreamIO devNull inh
166 , mkBench "catBracket" href $ do
167 Handles inh _ <- readIORef href
168 BFS.catBracket devNull inh
169 , mkBench "catBracketIO" href $ do
170 Handles inh _ <- readIORef href
171 BFS.catBracketIO devNull inh
173 , mkBench "read-word8" href $ do
174 Handles inh _ <- readIORef href
176 , mkBench "read-latin1" href $ do
177 Handles inh _ <- readIORef href
179 , mkBench "read-utf8" href $ do
180 Handles inh _ <- readIORef href
181 BFS.decodeUtf8Lax inh
184 [ mkBench "copy" href $ do
185 Handles inh outh <- readIORef href
189 -- This takes a little longer therefore put under the dev conditional
190 , bgroup "copyStream"
191 [ mkBench "fromToHandle" href $ do
192 Handles inh outh <- readIORef href
195 -- This needs an ascii file, as decode just errors out.
196 , bgroup "decode-encode"
197 [ mkBench "latin1" href $ do
198 Handles inh outh <- readIORef href
199 BFS.copyCodecChar8 inh outh
200 , mkBench "utf8-arrays" href $ do
201 Handles inh outh <- readIORef href
202 BFA.copyCodecUtf8Lenient inh outh
203 , mkBench "utf8" href $ do
204 Handles inh outh <- readIORef href
205 BFS.copyCodecUtf8Lenient inh outh
208 [ mkBench "chunksOf (single chunk)" href $ do
209 Handles inh _ <- readIORef href
210 BFS.chunksOf fileSize inh
212 , mkBench "chunksOf 1" href $ do
213 Handles inh _ <- readIORef href
215 , mkBench "chunksOf 10" href $ do
216 Handles inh _ <- readIORef href
218 , mkBench "chunksOf 1000" href $ do
219 Handles inh _ <- readIORef href
220 BFS.chunksOf 1000 inh
222 , bgroup "group-ungroup-stream"
223 [ mkBench "lines-unlines-[Char]" href $ do
224 Handles inh outh <- readIORef href
225 BFS.linesUnlinesCopy inh outh
226 , mkBench "lines-unlines-Word8Array" href $ do
227 Handles inh outh <- readIORef href
228 BFS.linesUnlinesArrayWord8Copy inh outh
229 , mkBench "lines-unlines-CharArray" href $ do
230 Handles inh outh <- readIORef href
231 BFS.linesUnlinesArrayCharCopy inh outh
232 , mkBench "words-unwords-[Word8]" href $ do
233 Handles inh outh <- readIORef href
234 BFS.wordsUnwordsCopyWord8 inh outh
235 , mkBench "words-unwords-[Char]" href $ do
236 Handles inh outh <- readIORef href
237 BFS.wordsUnwordsCopy inh outh
238 , mkBench "words-unwords-CharArray" href $ do
239 Handles inh outh <- readIORef href
240 BFS.wordsUnwordsCharArrayCopy inh outh
243 , bgroup "group-ungroup-array-stream"
244 [ mkBench "lines-unlines-Word8Array" href $ do
245 Handles inh outh <- readIORef href
246 BFA.linesUnlinesCopy inh outh
247 , mkBench "words-unwords-Word8Array" href $ do
248 Handles inh outh <- readIORef href
249 BFA.wordsUnwordsCopy inh outh
254 [ mkBench "splitOn \\n (line count)" href $ do
255 Handles inh _ <- readIORef href
257 , mkBench "splitOnSuffix \\n (line count)" href $ do
258 Handles inh _ <- readIORef href
259 BFS.splitOnSuffix inh
260 , mkBench "wordsBy isSpace (word count)" href $ do
261 Handles inh _ <- readIORef href
265 , bgroup "empty-pattern"
266 [ mkBench "splitOnSeq \"\"" href $ do
267 Handles inh _ <- readIORef href
268 BFS.splitOnSeq "" inh
269 , mkBench "splitOnSuffixSeq \"\"" href $ do
270 Handles inh _ <- readIORef href
271 BFS.splitOnSuffixSeq "" inh
273 , bgroup "short-pattern"
274 [ mkBench "splitOnSeq \\n (line count)" href $ do
275 Handles inh _ <- readIORef href
276 BFS.splitOnSeq "\n" inh
277 , mkBench "splitOnSuffixSeq \\n (line count)" href $ do
278 Handles inh _ <- readIORef href
279 BFS.splitOnSuffixSeq "\n" inh
280 , mkBench "splitOnSeq a" href $ do
281 Handles inh _ <- readIORef href
282 BFS.splitOnSeq "a" inh
283 , mkBench "splitOnSeq \\r\\n" href $ do
284 Handles inh _ <- readIORef href
285 BFS.splitOnSeq "\r\n" inh
286 , mkBench "splitOnSuffixSeq \\r\\n)" href $ do
287 Handles inh _ <- readIORef href
288 BFS.splitOnSuffixSeq "\r\n" inh
289 , mkBench "splitOnSeq aa" href $ do
290 Handles inh _ <- readIORef href
291 BFS.splitOnSeq "aa" inh
292 , mkBench "splitOnSeq aaaa" href $ do
293 Handles inh _ <- readIORef href
294 BFS.splitOnSeq "aaaa" inh
295 , mkBench "splitOnSeq abcdefgh" href $ do
296 Handles inh _ <- readIORef href
297 BFS.splitOnSeq "abcdefgh" inh
298 , mkBench "splitOnSeqUtf8 abcdefgh" href $ do
299 Handles inh _ <- readIORef href
300 BFS.splitOnSeqUtf8 "abcdefgh" inh
302 , bgroup "long-pattern"
303 [ mkBench "splitOnSeq abcdefghi" href $ do
304 Handles inh _ <- readIORef href
305 BFS.splitOnSeq "abcdefghi" inh
306 , mkBench "splitOnSeq catcatcatcatcat" href $ do
307 Handles inh _ <- readIORef href
308 BFS.splitOnSeq "catcatcatcatcat" inh
309 , mkBench "splitOnSeq abc...xyz" href $ do
310 Handles inh _ <- readIORef href
311 BFS.splitOnSeq "abcdefghijklmnopqrstuvwxyz" inh
312 , mkBench "splitOnSuffixSeq abc...xyz" href $ do
313 Handles inh _ <- readIORef href
314 BFS.splitOnSuffixSeq "abcdefghijklmnopqrstuvwxyz" inh
315 , mkBench "splitOnSeqUtf8 abc...xyz" href $ do
316 Handles inh _ <- readIORef href
317 BFS.splitOnSeqUtf8 "abcdefghijklmnopqrstuvwxyz" inh
325 mkBench :: NFData b => String -> IORef Handles -> IO b -> Benchmark
326 mkBench name ref action =
327 bench name $ perRunEnv (do
328 (Handles inh outh) <- readIORef ref
331 inHandle <- openFile infile ReadMode
332 outHandle <- openFile outfile WriteMode
333 writeIORef ref (Handles inHandle outHandle)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list