@@ -7,9 +7,12 @@
7-- Stability : experimental
7-- Stability : experimental
8-- Portability : GHC
8-- Portability : GHC
10{-# LANGUAGE TemplateHaskell #-}
12{-# LANGUAGE TemplateHaskell #-}
12{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
14{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
14module Streamly.Benchmark.FileIO.Stream
17module Streamly.Benchmark.FileIO.Stream
@@ -27,6 +30,7 @@ module Streamly.Benchmark.FileIO.Stream
27 , copyCodecChar8
30 , copyCodecChar8
28 , copyCodecUtf8
31 , copyCodecUtf8
29 , chunksOf
32 , chunksOf
31 , splitOnSuffix
35 , splitOnSuffix
@@ -40,30 +44,32 @@ import Data.Word (Word8)
40import System.IO (Handle)
44import System.IO (Handle)
41import Prelude hiding (last, length)
45import Prelude hiding (last, length)
43−import Streamly.Streams.StreamD.Type (Step(..), GroupState)
44−import Streamly.Benchmark.Inspection (hinspect)
45−import qualified Streamly.Memory.Array.Types as AT
47import qualified Streamly.FileSystem.Handle as FH
47import qualified Streamly.FileSystem.Handle as FH
48import qualified Streamly.FileSystem.Handle.Internal as FH
48import qualified Streamly.FileSystem.Handle.Internal as FH
49import qualified Streamly.Memory.Array as A
49import qualified Streamly.Memory.Array as A
50+import qualified Streamly.Memory.Array.Types as AT
50import qualified Streamly.Prelude.Internal as S
51import qualified Streamly.Prelude.Internal as S
51import qualified Streamly.Fold as FL
52import qualified Streamly.Fold as FL
52import qualified Streamly.Data.String as SS
53import qualified Streamly.Data.String as SS
53import qualified Streamly.Internal as Internal
54import qualified Streamly.Internal as Internal
54import qualified Streamly.Streams.StreamD as D
55import qualified Streamly.Streams.StreamD as D
58+import Streamly.Streams.StreamD.Type (Step(..), GroupState)
56import Test.Inspection
59import Test.Inspection
58-- | Get the last byte from a file bytestream.
62-- | Get the last byte from a file bytestream.
59{-# INLINE last #-}
63{-# INLINE last #-}
60last :: Handle -> IO (Maybe Word8)
64last :: Handle -> IO (Maybe Word8)
61last = S.last . FH.read
65last = S.last . FH.read
63−hinspect $ hasNoTypeClasses 'last
68+inspect $ hasNoTypeClasses 'last
64−hinspect $ 'last `hasNoType` ''Step
69+inspect $ 'last `hasNoType` ''Step
65−hinspect $ 'last `hasNoType` ''AT.FlattenState
70+inspect $ 'last `hasNoType` ''AT.FlattenState
66−hinspect $ 'last `hasNoType` ''D.ConcatMapUState
71+inspect $ 'last `hasNoType` ''D.ConcatMapUState
68-- assert that flattenArrays constructors are not present
74-- assert that flattenArrays constructors are not present
69-- | Count the number of bytes in a file.
75-- | Count the number of bytes in a file.
@@ -71,10 +77,12 @@ hinspect $ 'last `hasNoType` ''D.ConcatMapUState
71countBytes :: Handle -> IO Int
77countBytes :: Handle -> IO Int
72countBytes = S.length . FH.read
78countBytes = S.length . FH.read
74−hinspect $ hasNoTypeClasses 'countBytes
81+inspect $ hasNoTypeClasses 'countBytes
75−hinspect $ 'countBytes `hasNoType` ''Step
82+inspect $ 'countBytes `hasNoType` ''Step
76−hinspect $ 'countBytes `hasNoType` ''AT.FlattenState
83+inspect $ 'countBytes `hasNoType` ''AT.FlattenState
77−hinspect $ 'countBytes `hasNoType` ''D.ConcatMapUState
84+inspect $ 'countBytes `hasNoType` ''D.ConcatMapUState
79-- | Count the number of lines in a file.
87-- | Count the number of lines in a file.
80{-# INLINE countLines #-}
88{-# INLINE countLines #-}
@@ -85,10 +93,12 @@ countLines =
85 . SS.decodeChar8
93 . SS.decodeChar8
88−hinspect $ hasNoTypeClasses 'countLines
97+inspect $ hasNoTypeClasses 'countLines
89−hinspect $ 'countLines `hasNoType` ''Step
98+inspect $ 'countLines `hasNoType` ''Step
90−hinspect $ 'countLines `hasNoType` ''AT.FlattenState
99+inspect $ 'countLines `hasNoType` ''AT.FlattenState
91−hinspect $ 'countLines `hasNoType` ''D.ConcatMapUState
100+inspect $ 'countLines `hasNoType` ''D.ConcatMapUState
93-- | Count the number of lines in a file.
103-- | Count the number of lines in a file.
94{-# INLINE countLinesU #-}
104{-# INLINE countLinesU #-}
@@ -99,49 +109,59 @@ countLinesU inh =
99 $ SS.decodeChar8
109 $ SS.decodeChar8
100 $ Internal.concatMapU Internal.readU (FH.readArrays inh)
110 $ Internal.concatMapU Internal.readU (FH.readArrays inh)
102−hinspect $ hasNoTypeClasses 'countLinesU
113+inspect $ hasNoTypeClasses 'countLinesU
103−hinspect $ 'countLinesU `hasNoType` ''Step
114+inspect $ 'countLinesU `hasNoType` ''Step
104−hinspect $ 'countLinesU `hasNoType` ''D.ConcatMapUState
115+inspect $ 'countLinesU `hasNoType` ''D.ConcatMapUState
106-- | Sum the bytes in a file.
118-- | Sum the bytes in a file.
107{-# INLINE sumBytes #-}
119{-# INLINE sumBytes #-}
108sumBytes :: Handle -> IO Word8
120sumBytes :: Handle -> IO Word8
109sumBytes = S.sum . FH.read
121sumBytes = S.sum . FH.read
111−hinspect $ hasNoTypeClasses 'sumBytes
124+inspect $ hasNoTypeClasses 'sumBytes
112−hinspect $ 'sumBytes `hasNoType` ''Step
125+inspect $ 'sumBytes `hasNoType` ''Step
113−hinspect $ 'sumBytes `hasNoType` ''AT.FlattenState
126+inspect $ 'sumBytes `hasNoType` ''AT.FlattenState
114−hinspect $ 'sumBytes `hasNoType` ''D.ConcatMapUState
127+inspect $ 'sumBytes `hasNoType` ''D.ConcatMapUState
116-- | Send the file contents to /dev/null
130-- | Send the file contents to /dev/null
117{-# INLINE cat #-}
131{-# INLINE cat #-}
118cat :: Handle -> Handle -> IO ()
132cat :: Handle -> Handle -> IO ()
119cat devNull inh = S.runFold (FH.write devNull) $ FH.read inh
133cat devNull inh = S.runFold (FH.write devNull) $ FH.read inh
121−hinspect $ hasNoTypeClasses 'cat
136+inspect $ hasNoTypeClasses 'cat
122−hinspect $ 'cat `hasNoType` ''Step
137+inspect $ 'cat `hasNoType` ''Step
123−hinspect $ 'cat `hasNoType` ''AT.FlattenState
138+inspect $ 'cat `hasNoType` ''AT.FlattenState
124−hinspect $ 'cat `hasNoType` ''D.ConcatMapUState
139+inspect $ 'cat `hasNoType` ''D.ConcatMapUState
126-- | Send the file contents to /dev/null
142-- | Send the file contents to /dev/null
127{-# INLINE catStreamWrite #-}
143{-# INLINE catStreamWrite #-}
128catStreamWrite :: Handle -> Handle -> IO ()
144catStreamWrite :: Handle -> Handle -> IO ()
129catStreamWrite devNull inh = FH.writeS devNull $ FH.read inh
145catStreamWrite devNull inh = FH.writeS devNull $ FH.read inh
131−hinspect $ hasNoTypeClasses 'catStreamWrite
148+inspect $ hasNoTypeClasses 'catStreamWrite
132−hinspect $ 'catStreamWrite `hasNoType` ''Step
149+inspect $ 'catStreamWrite `hasNoType` ''Step
133−hinspect $ 'catStreamWrite `hasNoType` ''AT.FlattenState
150+inspect $ 'catStreamWrite `hasNoType` ''AT.FlattenState
134−hinspect $ 'catStreamWrite `hasNoType` ''D.ConcatMapUState
151+inspect $ 'catStreamWrite `hasNoType` ''D.ConcatMapUState
136-- | Copy file
154-- | Copy file
137{-# INLINE copy #-}
155{-# INLINE copy #-}
138copy :: Handle -> Handle -> IO ()
156copy :: Handle -> Handle -> IO ()
139copy inh outh = S.runFold (FH.write outh) (FH.read inh)
157copy inh outh = S.runFold (FH.write outh) (FH.read inh)
141−hinspect $ hasNoTypeClasses 'copy
160+inspect $ hasNoTypeClasses 'copy
142−hinspect $ 'copy `hasNoType` ''Step
161+inspect $ 'copy `hasNoType` ''Step
143−hinspect $ 'copy `hasNoType` ''AT.FlattenState
162+inspect $ 'copy `hasNoType` ''AT.FlattenState
144−hinspect $ 'copy `hasNoType` ''D.ConcatMapUState
163+inspect $ 'copy `hasNoType` ''D.ConcatMapUState
146-- | Copy file
166-- | Copy file
147{-# INLINE copyCodecChar8 #-}
167{-# INLINE copyCodecChar8 #-}
@@ -152,10 +172,12 @@ copyCodecChar8 inh outh =
152 $ SS.decodeChar8
172 $ SS.decodeChar8
153 $ FH.read inh
173 $ FH.read inh
155−hinspect $ hasNoTypeClasses 'copyCodecChar8
176+inspect $ hasNoTypeClasses 'copyCodecChar8
156−hinspect $ 'copyCodecChar8 `hasNoType` ''Step
177+inspect $ 'copyCodecChar8 `hasNoType` ''Step
157−hinspect $ 'copyCodecChar8 `hasNoType` ''AT.FlattenState
178+inspect $ 'copyCodecChar8 `hasNoType` ''AT.FlattenState
158−hinspect $ 'copyCodecChar8 `hasNoType` ''D.ConcatMapUState
179+inspect $ 'copyCodecChar8 `hasNoType` ''D.ConcatMapUState
160-- | Copy file
182-- | Copy file
161{-# INLINE copyCodecUtf8 #-}
183{-# INLINE copyCodecUtf8 #-}
@@ -166,10 +188,12 @@ copyCodecUtf8 inh outh =
166 $ SS.decodeUtf8
188 $ SS.decodeUtf8
167 $ FH.read inh
189 $ FH.read inh
169−hinspect $ hasNoTypeClasses 'copyCodecUtf8
192+inspect $ hasNoTypeClasses 'copyCodecUtf8
170−-- hinspect $ 'copyCodecUtf8 `hasNoType` ''Step
193+-- inspect $ 'copyCodecUtf8 `hasNoType` ''Step
171−-- hinspect $ 'copyCodecUtf8 `hasNoType` ''AT.FlattenState
194+-- inspect $ 'copyCodecUtf8 `hasNoType` ''AT.FlattenState
172−-- hinspect $ 'copyCodecUtf8 `hasNoType` ''D.ConcatMapUState
195+-- inspect $ 'copyCodecUtf8 `hasNoType` ''D.ConcatMapUState
174-- | Slice in chunks of size n and get the count of chunks.
198-- | Slice in chunks of size n and get the count of chunks.
175{-# INLINE chunksOf #-}
199{-# INLINE chunksOf #-}
@@ -178,11 +202,13 @@ chunksOf n inh =
178 -- writeNUnsafe gives 2.5x boost here over writeN.
202 -- writeNUnsafe gives 2.5x boost here over writeN.
179 S.length $ S.chunksOf n (AT.writeNUnsafe n) (FH.read inh)
203 S.length $ S.chunksOf n (AT.writeNUnsafe n) (FH.read inh)
181−hinspect $ hasNoTypeClasses 'chunksOf
206+inspect $ hasNoTypeClasses 'chunksOf
182−hinspect $ 'chunksOf `hasNoType` ''Step
207+inspect $ 'chunksOf `hasNoType` ''Step
183−hinspect $ 'chunksOf `hasNoType` ''AT.FlattenState
208+inspect $ 'chunksOf `hasNoType` ''AT.FlattenState
184−hinspect $ 'chunksOf `hasNoType` ''D.ConcatMapUState
209+inspect $ 'chunksOf `hasNoType` ''D.ConcatMapUState
185−hinspect $ 'chunksOf `hasNoType` ''GroupState
210+inspect $ 'chunksOf `hasNoType` ''GroupState
187-- This is to make sure that the concatMap in FH.read, groupsOf and foldlM'
213-- This is to make sure that the concatMap in FH.read, groupsOf and foldlM'
188-- together can fuse.
214-- together can fuse.
@@ -195,11 +221,13 @@ chunksOfD n inh =
195 $ D.groupsOf n (AT.writeNUnsafe n)
221 $ D.groupsOf n (AT.writeNUnsafe n)
196 $ D.fromStreamK (FH.read inh)
222 $ D.fromStreamK (FH.read inh)
198−hinspect $ hasNoTypeClasses 'chunksOf
225+inspect $ hasNoTypeClasses 'chunksOf
199−hinspect $ 'chunksOf `hasNoType` ''Step
226+inspect $ 'chunksOf `hasNoType` ''Step
200−hinspect $ 'chunksOfD `hasNoType` ''GroupState
227+inspect $ 'chunksOfD `hasNoType` ''GroupState
201−hinspect $ 'chunksOfD `hasNoType` ''AT.FlattenState
228+inspect $ 'chunksOfD `hasNoType` ''AT.FlattenState
202−hinspect $ 'chunksOfD `hasNoType` ''D.ConcatMapUState
229+inspect $ 'chunksOfD `hasNoType` ''D.ConcatMapUState
204-- | Lines and unlines
232-- | Lines and unlines
205{-# INLINE linesUnlinesCopy #-}
233{-# INLINE linesUnlinesCopy #-}
@@ -212,10 +240,12 @@ linesUnlinesCopy inh outh =
212 $ SS.decodeChar8
240 $ SS.decodeChar8
213 $ FH.read inh
241 $ FH.read inh
215−-- hinspect $ hasNoTypeClasses 'linesUnlinesCopy
244+-- inspect $ hasNoTypeClasses 'linesUnlinesCopy
216−-- hinspect $ 'linesUnlinesCopy `hasNoType` ''Step
245+-- inspect $ 'linesUnlinesCopy `hasNoType` ''Step
217−-- hinspect $ 'linesUnlinesCopy `hasNoType` ''AT.FlattenState
246+-- inspect $ 'linesUnlinesCopy `hasNoType` ''AT.FlattenState
218−-- hinspect $ 'linesUnlinesCopy `hasNoType` ''D.ConcatMapUState
247+-- inspect $ 'linesUnlinesCopy `hasNoType` ''D.ConcatMapUState
220-- | Word, unwords and copy
250-- | Word, unwords and copy
221{-# INLINE wordsUnwordsCopy #-}
251{-# INLINE wordsUnwordsCopy #-}
@@ -228,10 +258,12 @@ wordsUnwordsCopy inh outh =
228 $ SS.decodeChar8
258 $ SS.decodeChar8
229 $ FH.read inh
259 $ FH.read inh
231−-- hinspect $ hasNoTypeClasses 'wordsUnwordsCopy
262+-- inspect $ hasNoTypeClasses 'wordsUnwordsCopy
232−-- hinspect $ 'wordsUnwordsCopy `hasNoType` ''Step
263+-- inspect $ 'wordsUnwordsCopy `hasNoType` ''Step
233−-- hinspect $ 'wordsUnwordsCopy `hasNoType` ''AT.FlattenState
264+-- inspect $ 'wordsUnwordsCopy `hasNoType` ''AT.FlattenState
234−-- hinspect $ 'wordsUnwordsCopy `hasNoType` ''D.ConcatMapUState
265+-- inspect $ 'wordsUnwordsCopy `hasNoType` ''D.ConcatMapUState
236lf :: Word8
268lf :: Word8
237lf = fromIntegral (ord '\n')
269lf = fromIntegral (ord '\n')
@@ -267,10 +299,12 @@ splitOn inh =
267 (S.length $ S.splitOn (== lf) FL.drain
299 (S.length $ S.splitOn (== lf) FL.drain
268 $ FH.read inh) -- >>= print
300 $ FH.read inh) -- >>= print
270−hinspect $ hasNoTypeClasses 'splitOn
303+inspect $ hasNoTypeClasses 'splitOn
271−hinspect $ 'splitOn `hasNoType` ''Step
304+inspect $ 'splitOn `hasNoType` ''Step
272−hinspect $ 'splitOn `hasNoType` ''AT.FlattenState
305+inspect $ 'splitOn `hasNoType` ''AT.FlattenState
273−hinspect $ 'splitOn `hasNoType` ''D.ConcatMapUState
306+inspect $ 'splitOn `hasNoType` ''D.ConcatMapUState
275-- | Split suffix on line feed.
309-- | Split suffix on line feed.
276{-# INLINE splitOnSuffix #-}
310{-# INLINE splitOnSuffix #-}
@@ -279,10 +313,12 @@ splitOnSuffix inh =
279 (S.length $ S.splitOnSuffix (== lf) FL.drain
313 (S.length $ S.splitOnSuffix (== lf) FL.drain
280 $ FH.read inh) -- >>= print
314 $ FH.read inh) -- >>= print
282−hinspect $ hasNoTypeClasses 'splitOnSuffix
317+inspect $ hasNoTypeClasses 'splitOnSuffix
283−hinspect $ 'splitOnSuffix `hasNoType` ''Step
318+inspect $ 'splitOnSuffix `hasNoType` ''Step
284−hinspect $ 'splitOnSuffix `hasNoType` ''AT.FlattenState
319+inspect $ 'splitOnSuffix `hasNoType` ''AT.FlattenState
285−hinspect $ 'splitOnSuffix `hasNoType` ''D.ConcatMapUState
320+inspect $ 'splitOnSuffix `hasNoType` ''D.ConcatMapUState
287-- | Words by space
323-- | Words by space
288{-# INLINE wordsBy #-}
324{-# INLINE wordsBy #-}
@@ -291,10 +327,12 @@ wordsBy inh =
291 (S.length $ S.wordsBy isSp FL.drain
327 (S.length $ S.wordsBy isSp FL.drain
292 $ FH.read inh) -- >>= print
328 $ FH.read inh) -- >>= print
294−hinspect $ hasNoTypeClasses 'wordsBy
331+inspect $ hasNoTypeClasses 'wordsBy
295−hinspect $ 'wordsBy `hasNoType` ''Step
332+inspect $ 'wordsBy `hasNoType` ''Step
296−hinspect $ 'wordsBy `hasNoType` ''AT.FlattenState
333+inspect $ 'wordsBy `hasNoType` ''AT.FlattenState
297−hinspect $ 'wordsBy `hasNoType` ''D.ConcatMapUState
334+inspect $ 'wordsBy `hasNoType` ''D.ConcatMapUState
299-- | Split on a character sequence.
337-- | Split on a character sequence.
300{-# INLINE splitOnSeq #-}
338{-# INLINE splitOnSeq #-}
@@ -303,10 +341,12 @@ splitOnSeq str inh =
303 (S.length $ Internal.splitOnSeq (toarr str) FL.drain
341 (S.length $ Internal.splitOnSeq (toarr str) FL.drain
304 $ FH.read inh) -- >>= print
342 $ FH.read inh) -- >>= print
306−hinspect $ hasNoTypeClasses 'splitOnSeq
345+inspect $ hasNoTypeClasses 'splitOnSeq
307−-- hinspect $ 'splitOnSeq `hasNoType` ''Step
346+-- inspect $ 'splitOnSeq `hasNoType` ''Step
308−-- hinspect $ 'splitOnSeq `hasNoType` ''AT.FlattenState
347+-- inspect $ 'splitOnSeq `hasNoType` ''AT.FlattenState
309−-- hinspect $ 'splitOnSeq `hasNoType` ''D.ConcatMapUState
348+-- inspect $ 'splitOnSeq `hasNoType` ''D.ConcatMapUState
311-- | Split on suffix sequence.
351-- | Split on suffix sequence.
312{-# INLINE splitOnSuffixSeq #-}
352{-# INLINE splitOnSuffixSeq #-}
@@ -315,7 +355,9 @@ splitOnSuffixSeq str inh =
315 (S.length $ Internal.splitOnSuffixSeq (toarr str) FL.drain
355 (S.length $ Internal.splitOnSuffixSeq (toarr str) FL.drain
316 $ FH.read inh) -- >>= print
356 $ FH.read inh) -- >>= print
318−hinspect $ hasNoTypeClasses 'splitOnSuffixSeq
359+inspect $ hasNoTypeClasses 'splitOnSuffixSeq
319−-- hinspect $ 'splitOnSuffixSeq `hasNoType` ''Step
360+-- inspect $ 'splitOnSuffixSeq `hasNoType` ''Step
320−-- hinspect $ 'splitOnSuffixSeq `hasNoType` ''AT.FlattenState
361+-- inspect $ 'splitOnSuffixSeq `hasNoType` ''AT.FlattenState
321−-- hinspect $ 'splitOnSuffixSeq `hasNoType` ''D.ConcatMapUState
362+-- inspect $ 'splitOnSuffixSeq `hasNoType` ''D.ConcatMapUState