on e692bad help sign in
195 lines 5.2 kB history raw
1-- |
2-- Module : Streamly.Benchmark.FileIO.Array
3-- Copyright : (c) 2019 Composewell Technologies
4--
5-- License : BSD3
6-- Maintainer : harendra.kumar@gmail.com
7-- Stability : experimental
8-- Portability : GHC
10{-# LANGUAGE CPP #-}
12#ifdef __HADDOCK_VERSION__
13#undef INSPECTION
14#endif
16#ifdef INSPECTION
17{-# LANGUAGE TemplateHaskell #-}
18{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
19#endif
21module Streamly.Benchmark.FileIO.Array
22 (
23 last
24 , countBytes
25 , countLines
26 , countWords
27 , sumBytes
28 , cat
29 , copy
30 , linesUnlinesCopy
31 , wordsUnwordsCopy
32 , decodeUtf8Lenient
33 , copyCodecUtf8Lenient
34 )
35where
37import Data.Functor.Identity (runIdentity)
38import Data.Word (Word8)
39import System.IO (Handle)
40import Prelude hiding (last)
42import qualified Streamly.FileSystem.Handle as FH
43import qualified Streamly.Memory.Array as A
44import qualified Streamly.Prelude as S
45import qualified Streamly.Data.String as SS
46import qualified Streamly.Internal as Internal
48#ifdef INSPECTION
49import Foreign.Storable (Storable)
50import Streamly.Streams.StreamD.Type (Step(..))
51import Test.Inspection
52#endif
54-- | Get the last byte from a file bytestream.
55{-# INLINE last #-}
56last :: Handle -> IO (Maybe Word8)
57last inh = do
58 let s = FH.readArrays inh
59 larr <- S.last s
60 return $ case larr of
61 Nothing -> Nothing
62 Just arr -> A.readIndex arr (A.length arr - 1)
64#ifdef INSPECTION
65inspect $ hasNoTypeClasses 'last
66inspect $ 'last `hasNoType` ''Step
67#endif
69-- | Count the number of bytes in a file.
70{-# INLINE countBytes #-}
71countBytes :: Handle -> IO Int
72countBytes inh =
73 let s = FH.readArrays inh
74 in S.sum (S.map A.length s)
76#ifdef INSPECTION
77inspect $ hasNoTypeClasses 'countBytes
78inspect $ 'countBytes `hasNoType` ''Step
79#endif
81-- | Count the number of lines in a file.
82{-# INLINE countLines #-}
83countLines :: Handle -> IO Int
84countLines = S.length . A.splitOnSuffix 10 . FH.readArrays
86#ifdef INSPECTION
87inspect $ hasNoTypeClasses 'countLines
88inspect $ 'countLines `hasNoType` ''Step
89#endif
91-- XXX use a word splitting combinator instead of splitOn and test it.
92-- | Count the number of lines in a file.
93{-# INLINE countWords #-}
94countWords :: Handle -> IO Int
95countWords = S.length . A.splitOn 32 . FH.readArrays
97#ifdef INSPECTION
98inspect $ hasNoTypeClasses 'countWords
99inspect $ 'countWords `hasNoType` ''Step
100#endif
102-- | Sum the bytes in a file.
103{-# INLINE sumBytes #-}
104sumBytes :: Handle -> IO Word8
105sumBytes inh = do
106 let foldlArr' f z = runIdentity . S.foldl' f z . A.read
107 let s = FH.readArrays inh
108 S.foldl' (\acc arr -> acc + foldlArr' (+) 0 arr) 0 s
110#ifdef INSPECTION
111inspect $ hasNoTypeClasses 'sumBytes
112inspect $ 'sumBytes `hasNoType` ''Step
113#endif
115-- | Send the file contents to /dev/null
116{-# INLINE cat #-}
117cat :: Handle -> Handle -> IO ()
118cat devNull inh =
119 S.runFold (FH.writeArrays devNull) $ FH.readArraysOf (256*1024) inh
121#ifdef INSPECTION
122inspect $ hasNoTypeClasses 'cat
123inspect $ 'cat `hasNoType` ''Step
124#endif
126-- | Copy file
127{-# INLINE copy #-}
128copy :: Handle -> Handle -> IO ()
129copy inh outh =
130 let s = FH.readArrays inh
131 in S.runFold (FH.writeArrays outh) s
133#ifdef INSPECTION
134inspect $ hasNoTypeClasses 'copy
135inspect $ 'copy `hasNoType` ''Step
136#endif
138-- | Lines and unlines
139{-# INLINE linesUnlinesCopy #-}
140linesUnlinesCopy :: Handle -> Handle -> IO ()
141linesUnlinesCopy inh outh =
142 S.runFold (FH.writeArraysInChunksOf (1024*1024) outh)
143 $ Internal.insertAfterEach (return $ A.fromList [10])
144 $ A.splitOnSuffix 10
145 $ FH.readArraysOf (1024*1024) inh
147#ifdef INSPECTION
148inspect $ hasNoTypeClassesExcept 'linesUnlinesCopy [''Storable]
149-- inspect $ 'linesUnlinesCopy `hasNoType` ''Step
150#endif
152-- | Words and unwords
153{-# INLINE wordsUnwordsCopy #-}
154wordsUnwordsCopy :: Handle -> Handle -> IO ()
155wordsUnwordsCopy inh outh =
156 S.runFold (FH.writeArraysInChunksOf (1024*1024) outh)
157 $ S.intersperse (A.fromList [32])
158 -- XXX use a word splitting combinator
159 $ A.splitOn 32
160 $ FH.readArraysOf (1024*1024) inh
162#ifdef INSPECTION
163inspect $ hasNoTypeClassesExcept 'wordsUnwordsCopy [''Storable]
164-- inspect $ 'wordsUnwordsCopy `hasNoType` ''Step
165#endif
167{-# INLINE decodeUtf8Lenient #-}
168decodeUtf8Lenient :: Handle -> IO ()
169decodeUtf8Lenient inh =
170 S.drain
171 $ SS.decodeUtf8ArraysLenient
172 $ FH.readArraysOf (1024*1024) inh
174#ifdef INSPECTION
175inspect $ hasNoTypeClasses 'decodeUtf8Lenient
176-- inspect $ 'decodeUtf8Lenient `hasNoType` ''Step
177-- inspect $ 'decodeUtf8Lenient `hasNoType` ''AT.FlattenState
178-- inspect $ 'decodeUtf8Lenient `hasNoType` ''D.ConcatMapUState
179#endif
181-- | Copy file
182{-# INLINE copyCodecUtf8Lenient #-}
183copyCodecUtf8Lenient :: Handle -> Handle -> IO ()
184copyCodecUtf8Lenient inh outh =
185 S.runFold (FH.write outh)
186 $ SS.encodeUtf8
187 $ SS.decodeUtf8ArraysLenient
188 $ FH.readArraysOf (1024*1024) inh
190#ifdef INSPECTION
191inspect $ hasNoTypeClasses 'copyCodecUtf8Lenient
192-- inspect $ 'copyCodecUtf8Lenient `hasNoType` ''Step
193-- inspect $ 'copyCodecUtf8Lenient `hasNoType` ''AT.FlattenState
194-- inspect $ 'copyCodecUtf8Lenient `hasNoType` ''D.ConcatMapUState
195#endif