1{-# OPTIONS_GHC -Wno-deprecations #-}
2{-# OPTIONS_GHC -Wno-orphans #-}
5-- Module : Streamly.Benchmark.Data.Array.Unboxed.Mut
6-- Copyright : (c) 2021 Composewell Technologies
7-- License : BSD-3-Clause
8-- Maintainer : streamly@composewell.com
11{-# LANGUAGE FlexibleContexts #-}
12{-# LANGUAGE ScopedTypeVariables #-}
14#ifdef __HADDOCK_VERSION__
19{-# LANGUAGE TemplateHaskell #-}
20{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
23import Control.DeepSeq (NFData(..))
24import Control.Monad.IO.Class (MonadIO)
25import Data.Functor ((<&>))
26import System.Random (randomRIO)
45import Streamly.Internal.Data.MutArray (MutArray)
47import qualified Streamly.Internal.Data.Array as Array
48import qualified Streamly.Internal.Data.MutArray as MArray
49import qualified Streamly.Internal.Data.Fold as Fold
50import qualified Streamly.Internal.Data.Stream as Stream
52import Test.Tasty.Bench
53import Streamly.Benchmark.Common hiding (benchPureSrc)
57instance NFData (MutArray a) where
61-------------------------------------------------------------------------------
63-------------------------------------------------------------------------------
66benchIO :: NFData b => String -> (Int -> IO a) -> (a -> b) -> Benchmark
67benchIO name src f = bench name $ nfIO $
68 (randomRIO (1,1) >>= src) <&> f
70{-# INLINE benchPureSink #-}
71benchPureSink :: NFData b => Int -> String -> (Stream Int -> b) -> Benchmark
72benchPureSink value name = benchIO name (sourceIntFromTo value)
74{-# INLINE benchIO' #-}
75benchIO' :: NFData b => String -> (Int -> IO a) -> (a -> IO b) -> Benchmark
76benchIO' name src f = bench name $ nfIO $
77 randomRIO (1,1) >>= src >>= f
79{-# INLINE benchIOSink #-}
80benchIOSink :: NFData b => Int -> String -> (Stream Int -> IO b) -> Benchmark
81benchIOSink value name = benchIO' name (sourceIntFromTo value)
83-- Drain a source that generates an array in the IO monad
84{-# INLINE benchIOSrc #-}
85benchIOSrc :: String -> (Int -> IO (Stream a)) -> Benchmark
86benchIOSrc name src = benchIO name src id
88drain :: Monad m => Stream.Stream m a -> m ()
89drain = Stream.fold Fold.drain
91-------------------------------------------------------------------------------
93-------------------------------------------------------------------------------
95{-# INLINE sourceUnfoldr #-}
96sourceUnfoldr :: MonadIO m => Int -> Int -> m (Stream Int)
97sourceUnfoldr value n =
98 Stream.fold (MArray.writeN value) $ Stream.unfoldr step n
105 else Just (cnt, cnt + 1)
107{-# INLINE sourceIntFromTo #-}
108sourceIntFromTo :: MonadIO m => Int -> Int -> m (Stream Int)
109sourceIntFromTo value n =
110 Stream.fold (MArray.writeN value) $ Stream.enumerateFromTo n (n + value)
112{-# INLINE sourceFromList #-}
113sourceFromList :: MonadIO m => Int -> Int -> m (Stream Int)
114sourceFromList value n =
115 Stream.fold (MArray.writeN value) $ Stream.fromList [n .. n + value]
117{-# INLINE sourceIntFromToFromList #-}
118sourceIntFromToFromList :: MonadIO m => Int -> Int -> m (Stream Int)
119sourceIntFromToFromList value n = MArray.fromListN value [n..n + value]
121{-# INLINE sourceIntFromToFromStream #-}
122sourceIntFromToFromStream :: MonadIO m => Int -> Int -> m (Stream Int)
123sourceIntFromToFromStream value n =
124 Stream.fold MArray.write $ Stream.enumerateFromTo n (n + value)
126{-# INLINE sourceUnfoldrM #-}
127sourceUnfoldrM :: Monad m => Int -> Int -> Stream.Stream m Int
128sourceUnfoldrM value n = Stream.unfoldrM step n
133 else return (Just (cnt, cnt + 1))
135-------------------------------------------------------------------------------
137-------------------------------------------------------------------------------
139{-# INLINE composeN #-}
141 => Int -> (Stream Int -> m (Stream Int)) -> Stream Int -> m (Stream Int)
147 4 -> f x >>= f >>= f >>= f
151scanl' :: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
152scanl' value n = composeN n $ onArray value $ Stream.scan (Fold.foldl' (+) 0)
154{-# INLINE scanl1' #-}
155scanl1' :: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
156scanl1' value n = composeN n $ onArray value $ Stream.scanl1' (+)
159map :: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
160map value n = composeN n $ onArray value $ fmap (+ 1)
162{-# INLINE onArray #-}
164 :: MonadIO m => Int -> (Stream.Stream m Int -> Stream.Stream m Int)
168 Stream.fold (MArray.writeN value) $ f $ Stream.unfold MArray.reader arr
170-------------------------------------------------------------------------------
172-------------------------------------------------------------------------------
174{-# INLINE unfoldReadDrain #-}
175unfoldReadDrain :: MonadIO m => Stream Int -> m ()
176unfoldReadDrain = drain . Stream.unfold MArray.reader
178{-# INLINE unfoldReadRevDrain #-}
179unfoldReadRevDrain :: MonadIO m => Stream Int -> m ()
180unfoldReadRevDrain = drain . Stream.unfold MArray.readerRev
182{-# INLINE toStreamDRevDrain #-}
183toStreamDRevDrain :: MonadIO m => Stream Int -> m ()
184toStreamDRevDrain = drain . MArray.readRev
186{-# INLINE toStreamDDrain #-}
187toStreamDDrain :: MonadIO m => Stream Int -> m ()
188toStreamDDrain = drain . MArray.read
190{-# INLINE unfoldFold #-}
191unfoldFold :: MonadIO m => Stream Int -> m Int
192unfoldFold = Stream.fold (Fold.foldl' (+) 0) . Stream.unfold MArray.reader
194-------------------------------------------------------------------------------
196-------------------------------------------------------------------------------
198o_1_space_generation :: Int -> [Benchmark]
199o_1_space_generation value =
202 [ benchIOSrc "writeN . intFromTo" (sourceIntFromTo value)
204 "fromList . intFromTo"
205 (sourceIntFromToFromList value)
206 , benchIOSrc "writeN . unfoldr" (sourceUnfoldr value)
207 , benchIOSrc "writeN . fromList" (sourceFromList value)
208 , benchIOSrc "write . intFromTo" (sourceIntFromToFromStream value)
212o_1_space_elimination :: Int -> [Benchmark]
213o_1_space_elimination value =
214 [ bgroup "elimination"
215 [ benchPureSink value "id" id
216 , benchIOSink value "foldl'" unfoldFold
217 , benchIOSink value "read" unfoldReadDrain
218 , benchIOSink value "readRev" unfoldReadRevDrain
219 , benchIOSink value "toStream" toStreamDDrain
220 , benchIOSink value "toStreamRev" toStreamDRevDrain
224o_n_heap_serial :: Int -> [Benchmark]
225o_n_heap_serial value =
226 [ bgroup "elimination"
228 -- Converting the stream to an array
229 benchFold "writeN" (Stream.fold (MArray.writeN value))
230 (sourceUnfoldrM value)
234o_1_space_transformation :: Int -> [Benchmark]
235o_1_space_transformation value =
236 [ bgroup "transformation"
237 [ benchIOSink value "scanl'" (scanl' value 1)
238 , benchIOSink value "scanl1'" (scanl1' value 1)
239 , benchIOSink value "map" (map value 1)
243o_1_space_transformationX4 :: Int -> [Benchmark]
244o_1_space_transformationX4 value =
245 [ bgroup "transformationX4"
246 [ benchIOSink value "scanl'" (scanl' value 4)
247 , benchIOSink value "scanl1'" (scanl1' value 4)
248 , benchIOSink value "map" (map value 4)
252o_1_space_serial_marray ::
253 Int -> (MutArray Int, Array.Array Int) -> [Benchmark]
254o_1_space_serial_marray value ~(array, indices) =
255 [ benchIO' "partitionBy (< 0)" (const (return array))
256 $ MArray.partitionBy (< 0)
257 , benchIO' "partitionBy (> 0)" (const (return array))
258 $ MArray.partitionBy (> 0)
259 , benchIO' "partitionBy (< value/2)" (const (return array))
260 $ MArray.partitionBy (< (value `div` 2))
261 , benchIO' "partitionBy (> value/2)" (const (return array))
262 $ MArray.partitionBy (> (value `div` 2))
263 , benchIO' "strip (< value/2 || > value/2)" (const (return array))
264 $ MArray.strip (\x -> x < value `div` 2 || x > value `div` 2)
265 , benchIO' "strip (> 0)" (const (return array))
267 , benchIO' "modifyIndices (+ 1)" (const (return indices))
268 $ Stream.fold (MArray.modifyIndices array (\_idx val -> val + 1))
269 . Stream.unfold Array.reader
272-------------------------------------------------------------------------------
274-------------------------------------------------------------------------------
277moduleName = "Data.MutArray"
281 runWithCLIOptsEnv defaultStreamSize alloc allBenchmarks
286 marr <- MArray.fromStream (sourceUnfoldrM value 0 :: Stream.Stream IO Int)
287 indices <- Array.fromStream (sourceUnfoldrM value 0 :: Stream.Stream IO Int)
288 return (marr, indices)
290 allBenchmarks array value =
291 [ bgroup (o_1_space_prefix moduleName)
293 [ o_1_space_serial_marray value array
294 , o_1_space_generation value
295 , o_1_space_elimination value
296 , o_1_space_transformation value
297 , o_1_space_transformationX4 value
299 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
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