@@ -8,24 +8,14 @@
88{-# LANGUAGE CPP #-}
99
1010import Control.DeepSeq (NFData)
11−import Data.Functor.Identity (runIdentity)
1211import System.IO (openFile, IOMode(..), Handle, hClose)
1312import System.Process.Typed (shell, runProcess_)
1413
1514import Data.IORef
1615import Gauge
1716
18−import qualified Streamly.FileSystem.Handle as FH
19−import qualified Streamly.Memory.Array as A
20−import qualified Streamly.Prelude as S
21−import qualified Streamly.Fold as FL
22−import qualified Streamly.Data.String as SS
23−import qualified Streamly.Internal as Internal
24−
25−#ifdef DEVBUILD
26−import Data.Char (ord, chr)
27−import qualified Streamly.Internal as Internal
28−#endif
17+import qualified Streamly.Benchmark.FileIO.Stream as BFS
18+import qualified Streamly.Benchmark.FileIO.Array as BFA
2919
3020-- Input and output file handles
3121data Handles = Handles Handle Handle
@@ -51,23 +41,6 @@ infile = "benchmark/text-processing/gutenberg-500.txt"
5141fileSize :: Int
5242fileSize = blockSize * blockCount
5343
54−foreign import ccall unsafe "u_iswspace"
55− iswspace :: Int -> Int
56−
57−-- Code copied from base/Data.Char to INLINE it
58−{-# INLINE isSpace #-}
59−isSpace :: Char -> Bool
60−-- isSpace includes non-breaking space
61−-- The magic 0x377 isn't really that magical. As of 2014, all the codepoints
62−-- at or below 0x377 have been assigned, so we shouldn't have to worry about
63−-- any new spaces appearing below there. It would probably be best to
64−-- use branchless ||, but currently the eqLit transformation will undo that,
65−-- so we'll do it like this until there's a way around that.
66−isSpace c
67− | uc <= 0x377 = uc == 32 || uc - 0x9 <= 4 || uc == 0xa0
68− | otherwise = iswspace (ord c) /= 0
69− where
70− uc = fromIntegral (ord c) :: Word
7144#else
7245infile :: String
7346infile = scratchDir ++ "in-100MB.txt"
@@ -96,213 +69,154 @@ main = do
9669 [ bgroup "readArray"
9770 [ mkBench "last" href $ do
9871 Handles inh _ <- readIORef href
99− let s = FH.readArrays inh
100− larr <- S.last s
101− return $ case larr of
102− Nothing -> Nothing
103− Just arr -> A.readIndex arr (A.length arr - 1)
72+ BFA.last inh
10473 -- Note: this cannot be fairly compared with GNU wc -c or wc -m as
10574 -- wc uses lseek to just determine the file size rather than reading
10675 -- and counting characters.
10776 , mkBench "length (bytecount)" href $ do
10877 Handles inh _ <- readIORef href
109− let s = FH.readArrays inh
110− S.sum (S.map A.length s)
78+ BFA.countBytes inh
11179 , mkBench "linecount" href $ do
11280 Handles inh _ <- readIORef href
113− S.length $ A.splitOn 10 $ FH.readArrays inh
81+ BFA.countLines inh
11482 , mkBench "sum" href $ do
115− let foldlArr' f z = runIdentity . S.foldl' f z . A.read
11683 Handles inh _ <- readIORef href
117− let s = FH.readArrays inh
118− S.foldl' (\acc arr -> acc + foldlArr' (+) 0 arr) 0 s
84+ BFA.sumBytes inh
11985 , mkBench "cat" href $ do
12086 Handles inh _ <- readIORef href
121− S.runFold (FH.writeArrays devNull) $ FH.readArraysOf (256*1024) inh
87+ BFA.cat devNull inh
12288 ]
12389 , bgroup "readStream"
12490 [ mkBench "last" href $ do
12591 Handles inh _ <- readIORef href
126− S.last $ FH.read inh
92+ BFS.last inh
12793 , mkBench "length (bytecount)" href $ do
12894 Handles inh _ <- readIORef href
129− S.length $ FH.read inh
95+ BFS.countBytes inh
13096 , mkBench "linecount" href $ do
13197 Handles inh _ <- readIORef href
132− S.length
133− $ SS.foldLines FL.drain
134− $ SS.decodeChar8
135− $ FH.read inh
98+ BFS.countLines inh
13699 , mkBench "linecountU" href $ do
137100 Handles inh _ <- readIORef href
138− S.length
139− $ SS.foldLines FL.drain
140− $ SS.decodeChar8
141− $ Internal.concatMapU Internal.readU (FH.readArrays inh)
101+ BFS.countLinesU inh
142102 , mkBench "sum" href $ do
143103 Handles inh _ <- readIORef href
144− S.sum $ FH.read inh
104+ BFS.sumBytes inh
145105 , mkBench "cat" href $ do
146106 Handles inh _ <- readIORef href
147− S.runFold (FH.write devNull) $ FH.read inh
107+ BFS.cat devNull inh
148108 , mkBench "catStream" href $ do
149109 Handles inh _ <- readIORef href
150− Internal.writeS devNull $ FH.read inh
110+ BFS.catStreamWrite devNull inh
151111 ]
152112 , bgroup "copyArray"
153113 [ mkBench "copy" href $ do
154114 Handles inh outh <- readIORef href
155− let s = FH.readArrays inh
156− S.runFold (FH.writeArrays outh) s
115+ BFA.copy inh outh
157116 ]
158117#ifdef DEVBUILD
159118 -- This takes a little longer therefore put under the dev conditional
160119 , bgroup "copyStream"
161120 [ mkBench "fromToHandle" href $ do
162121 Handles inh outh <- readIORef href
163− S.runFold (FH.write outh) (FH.read inh)
122+ BFS.copy inh outh
164123 ]
165124 -- This needs an ascii file, as decode just errors out.
166125 , bgroup "decode-encode"
167126 [ mkBench "char8" href $ do
168127 Handles inh outh <- readIORef href
169− S.runFold (FH.write outh)
170− $ SS.encodeChar8
171− $ SS.decodeChar8
172− $ FH.read inh
128+ BFS.copyCodecChar8 inh outh
173129 , mkBench "utf8" href $ do
174130 Handles inh outh <- readIORef href
175− S.runFold (FH.write outh)
176− $ SS.encodeUtf8
177− $ SS.decodeUtf8
178− $ FH.read inh
131+ BFS.copyCodecUtf8 inh outh
179132 ]
180133 , bgroup "grouping"
181− [ mkBench "chunksOf 1 (A.writeNF)" href $ do
134+ [ mkBench "chunksOf 1 (A.writeN)" href $ do
182135 Handles inh _ <- readIORef href
183− S.length $ S.chunksOf fileSize (A.writeN fileSize)
184− (FH.read inh)
136+ BFS.chunksOf fileSize inh
185137
186138 , mkBench "chunksOf 1" href $ do
187139 Handles inh _ <- readIORef href
188− S.length $ S.chunksOf 1 FL.drain (FH.read inh)
140+ BFS.chunksOf 1 inh
189141 , mkBench "chunksOf 10" href $ do
190142 Handles inh _ <- readIORef href
191− S.length $ S.chunksOf 10 FL.drain (FH.read inh)
143+ BFS.chunksOf 10 inh
192144 , mkBench "chunksOf 1000" href $ do
193145 Handles inh _ <- readIORef href
194− S.length $ S.chunksOf 1000 FL.drain (FH.read inh)
146+ BFS.chunksOf 1000 inh
195147 ]
196148 , bgroup "group-ungroup"
197149 [ mkBench "lines-unlines" href $ do
198150 Handles inh outh <- readIORef href
199− S.runFold (FH.write outh)
200− $ SS.encodeChar8
201− $ SS.unlines
202− $ SS.lines
203− $ SS.decodeChar8
204− $ FH.read inh
151+ BFS.linesUnlinesCopy inh outh
205152 , mkBench "lines-unlines-arrays" href $ do
206153 Handles inh outh <- readIORef href
207− S.runFold (FH.writeArraysInChunksOf (1024*1024) outh)
208− $ Internal.insertAfterEach (return $ A.fromList [10])
209− $ A.splitOn 10
210− $ FH.readArraysOf (1024*1024) inh
154+ BFA.linesUnlinesCopy inh outh
211155 , mkBench "words-unwords" href $ do
212156 Handles inh outh <- readIORef href
213− S.runFold (FH.write outh)
214− $ SS.encodeChar8
215− $ SS.unwords
216− $ SS.words
217− $ SS.decodeChar8
218− $ FH.read inh
157+ BFS.wordsUnwordsCopy inh outh
219158 ]
220159
221− , let lf = fromIntegral (ord '\n')
222− lfarr = A.fromList [lf]
223− isSp = isSpace . chr . fromIntegral
224− toarr = A.fromList . map (fromIntegral . ord)
225− in bgroup "splitting"
160+ , bgroup "splitting"
226161 [ bgroup "predicate"
227162 [ mkBench "splitOn \\n (line count)" href $ do
228163 Handles inh _ <- readIORef href
229− (S.length $ S.splitOn (== lf) FL.drain
230− $ FH.read inh) -- >>= print
164+ BFS.splitOn inh
231165 , mkBench "splitOnSuffix \\n (line count)" href $ do
232166 Handles inh _ <- readIORef href
233− (S.length $ S.splitOnSuffix (== lf) FL.drain
234− $ FH.read inh) -- >>= print
167+ BFS.splitOnSuffix inh
235168 , mkBench "wordsBy isSpace (word count)" href $ do
236169 Handles inh _ <- readIORef href
237− (S.length $ S.wordsBy isSp FL.drain
238− $ FH.read inh) -- >>= print
170+ BFS.wordsBy inh
239171 ]
240172
241173 , bgroup "empty-pattern"
242174 [ mkBench "splitOnSeq \"\"" href $ do
243175 Handles inh _ <- readIORef href
244− (S.length $ Internal.splitOnSeq (A.fromList []) FL.drain
245− $ FH.read inh) -- >>= print
176+ BFS.splitOnSeq "" inh
246177 , mkBench "splitOnSuffixSeq \"\"" href $ do
247178 Handles inh _ <- readIORef href
248− (S.length $ Internal.splitOnSuffixSeq (A.fromList []) FL.drain
249− $ FH.read inh) -- >>= print
179+ BFS.splitOnSuffixSeq "" inh
250180 ]
251181 , bgroup "short-pattern"
252182 [ mkBench "splitOnSeq \\n (line count)" href $ do
253183 Handles inh _ <- readIORef href
254− (S.length $ Internal.splitOnSeq lfarr FL.drain
255− $ FH.read inh) -- >>= print
184+ BFS.splitOnSeq "\n" inh
256185 , mkBench "splitOnSuffixSeq \\n (line count)" href $ do
257186 Handles inh _ <- readIORef href
258− (S.length $ Internal.splitOnSuffixSeq lfarr FL.drain
259− $ FH.read inh) -- >>= print
187+ BFS.splitOnSuffixSeq "\n" inh
260188 , mkBench "splitOnSeq a" href $ do
261189 Handles inh _ <- readIORef href
262− (S.length $ Internal.splitOnSeq (toarr "a") FL.drain
263− $ FH.read inh) -- >>= print
190+ BFS.splitOnSeq "a" inh
264191 , mkBench "splitOnSeq \\r\\n" href $ do
265192 Handles inh _ <- readIORef href
266− (S.length $ Internal.splitOnSeq (toarr "\r\n") FL.drain
267− $ FH.read inh) -- >>= print
193+ BFS.splitOnSeq "\r\n" inh
268194 , mkBench "splitOnSuffixSeq \\r\\n)" href $ do
269195 Handles inh _ <- readIORef href
270− (S.length $ Internal.splitOnSuffixSeq (toarr "\r\n") FL.drain
271− $ FH.read inh) -- >>= print
196+ BFS.splitOnSuffixSeq "\r\n" inh
272197 , mkBench "splitOnSeq aa" href $ do
273198 Handles inh _ <- readIORef href
274− (S.length $ Internal.splitOnSeq (toarr "aa") FL.drain
275− $ FH.read inh) -- >>= print
199+ BFS.splitOnSeq "aa" inh
276200 , mkBench "splitOnSeq aaaa" href $ do
277201 Handles inh _ <- readIORef href
278− (S.length $ Internal.splitOnSeq (toarr "aaaa") FL.drain
279− $ FH.read inh) -- >>= print
202+ BFS.splitOnSeq "aaaa" inh
280203 , mkBench "splitOnSeq abcdefgh" href $ do
281204 Handles inh _ <- readIORef href
282− (S.length $ Internal.splitOnSeq (toarr "abcdefgh") FL.drain
283− $ FH.read inh) -- >>= print
205+ BFS.splitOnSeq "abcdefgh" inh
284206 ]
285207 , bgroup "long-pattern"
286208 [ mkBench "splitOnSeq abcdefghi" href $ do
287209 Handles inh _ <- readIORef href
288− (S.length $ Internal.splitOnSeq (toarr "abcdefghi") FL.drain
289− $ FH.read inh) -- >>= print
210+ BFS.splitOnSeq "abcdefghi" inh
290211 , mkBench "splitOnSeq catcatcatcatcat" href $ do
291212 Handles inh _ <- readIORef href
292− (S.length $ Internal.splitOnSeq (toarr "catcatcatcatcat") FL.drain
293− $ FH.read inh) -- >>= print
213+ BFS.splitOnSeq "catcatcatcatcat" inh
294214 , mkBench "splitOnSeq abc...xyz" href $ do
295215 Handles inh _ <- readIORef href
296− (S.length $ Internal.splitOnSeq
297− (toarr "abcdefghijklmnopqrstuvwxyz")
298− FL.drain
299− $ FH.read inh) -- >>= print
216+ BFS.splitOnSeq "abcdefghijklmnopqrstuvwxyz" inh
300217 , mkBench "splitOnSuffixSeq abc...xyz" href $ do
301218 Handles inh _ <- readIORef href
302− (S.length $ Internal.splitOnSuffixSeq
303− (toarr "abcdefghijklmnopqrstuvwxyz")
304− FL.drain
305− $ FH.read inh) -- >>= print
219+ BFS.splitOnSuffixSeq "abcdefghijklmnopqrstuvwxyz" inh
306220 ]
307221 ]
308222#endif