2-- Module : Streamly.Benchmark.Data.Array.Unboxed.Mut
3-- Copyright : (c) 2021 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
8{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE ScopedTypeVariables #-}
11#ifdef __HADDOCK_VERSION__
16{-# LANGUAGE TemplateHaskell #-}
17{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
20import Control.DeepSeq (NFData(..))
21import Control.Monad.IO.Class (MonadIO)
22import Data.Functor ((<&>))
23import System.Random (randomRIO)
43import qualified Streamly.Internal.Data.Array.Unboxed as Array
44import qualified Streamly.Internal.Data.Array.Unboxed.Mut as MArray
45import qualified Streamly.Internal.Data.Fold as Fold
46import qualified Streamly.Internal.Data.Stream as Stream
47import qualified Streamly.Prelude as IsStream (scanl1')
50import Streamly.Benchmark.Common hiding (benchPureSrc)
52type Stream = MArray.Array
54-------------------------------------------------------------------------------
56-------------------------------------------------------------------------------
59benchIO :: NFData b => String -> (Int -> IO a) -> (a -> b) -> Benchmark
60benchIO name src f = bench name $ nfIO $
61 (randomRIO (1,1) >>= src) <&> f
63{-# INLINE benchPureSink #-}
64benchPureSink :: NFData b => Int -> String -> (Stream Int -> b) -> Benchmark
65benchPureSink value name = benchIO name (sourceIntFromTo value)
67{-# INLINE benchIO' #-}
68benchIO' :: NFData b => String -> (Int -> IO a) -> (a -> IO b) -> Benchmark
69benchIO' name src f = bench name $ nfIO $
70 randomRIO (1,1) >>= src >>= f
72{-# INLINE benchIOSink #-}
73benchIOSink :: NFData b => Int -> String -> (Stream Int -> IO b) -> Benchmark
74benchIOSink value name = benchIO' name (sourceIntFromTo value)
76-- Drain a source that generates an array in the IO monad
77{-# INLINE benchIOSrc #-}
78benchIOSrc :: String -> (Int -> IO (Stream a)) -> Benchmark
79benchIOSrc name src = benchIO name src id
81drain :: Monad m => Stream.Stream m a -> m ()
82drain = Stream.fold Fold.drain
84-------------------------------------------------------------------------------
86-------------------------------------------------------------------------------
88{-# INLINE sourceUnfoldr #-}
89sourceUnfoldr :: MonadIO m => Int -> Int -> m (Stream Int)
90sourceUnfoldr value n =
91 Stream.fold (MArray.writeN value) $ Stream.unfoldr step n
98 else Just (cnt, cnt + 1)
100{-# INLINE sourceIntFromTo #-}
101sourceIntFromTo :: MonadIO m => Int -> Int -> m (Stream Int)
102sourceIntFromTo value n =
103 Stream.fold (MArray.writeN value) $ Stream.enumerateFromTo n (n + value)
105{-# INLINE sourceFromList #-}
106sourceFromList :: MonadIO m => Int -> Int -> m (Stream Int)
107sourceFromList value n =
108 Stream.fold (MArray.writeN value) $ Stream.fromList [n .. n + value]
110{-# INLINE sourceIntFromToFromList #-}
111sourceIntFromToFromList :: MonadIO m => Int -> Int -> m (Stream Int)
112sourceIntFromToFromList value n = MArray.fromListN value [n..n + value]
114{-# INLINE sourceIntFromToFromStream #-}
115sourceIntFromToFromStream :: MonadIO m => Int -> Int -> m (Stream Int)
116sourceIntFromToFromStream value n =
117 Stream.fold MArray.write $ Stream.enumerateFromTo n (n + value)
119{-# INLINE sourceUnfoldrM #-}
120sourceUnfoldrM :: Monad m => Int -> Int -> Stream.Stream m Int
121sourceUnfoldrM value n = Stream.unfoldrM step n
126 else return (Just (cnt, cnt + 1))
128-------------------------------------------------------------------------------
130-------------------------------------------------------------------------------
132{-# INLINE composeN #-}
134 => Int -> (Stream Int -> m (Stream Int)) -> Stream Int -> m (Stream Int)
140 4 -> f x >>= f >>= f >>= f
144scanl' :: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
145scanl' value n = composeN n $ onArray value $ Stream.scan (Fold.foldl' (+) 0)
147{-# INLINE scanl1' #-}
148scanl1' :: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
149scanl1' value n = composeN n $ onArray value $ IsStream.scanl1' (+)
152map :: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
153map value n = composeN n $ onArray value $ fmap (+ 1)
155{-# INLINE onArray #-}
157 :: MonadIO m => Int -> (Stream.Stream m Int -> Stream.Stream m Int)
161 Stream.fold (MArray.writeN value) $ f $ Stream.unfold MArray.read arr
163-------------------------------------------------------------------------------
165-------------------------------------------------------------------------------
167{-# INLINE unfoldReadDrain #-}
168unfoldReadDrain :: MonadIO m => Stream Int -> m ()
169unfoldReadDrain = drain . Stream.unfold MArray.read
171{-# INLINE unfoldReadRevDrain #-}
172unfoldReadRevDrain :: MonadIO m => Stream Int -> m ()
173unfoldReadRevDrain = drain . Stream.unfold MArray.readRev
175{-# INLINE toStreamDRevDrain #-}
176toStreamDRevDrain :: MonadIO m => Stream Int -> m ()
178 drain . Stream.fromStreamD . MArray.toStreamDRev
180{-# INLINE toStreamDDrain #-}
181toStreamDDrain :: MonadIO m => Stream Int -> m ()
182toStreamDDrain = drain . Stream.fromStreamD . MArray.toStreamD
184{-# INLINE unfoldFold #-}
185unfoldFold :: MonadIO m => Stream Int -> m Int
186unfoldFold = Stream.fold (Fold.foldl' (+) 0) . Stream.unfold MArray.read
188-------------------------------------------------------------------------------
190-------------------------------------------------------------------------------
192o_1_space_generation :: Int -> [Benchmark]
193o_1_space_generation value =
196 [ benchIOSrc "writeN . intFromTo" (sourceIntFromTo value)
198 "fromList . intFromTo"
199 (sourceIntFromToFromList value)
200 , benchIOSrc "writeN . unfoldr" (sourceUnfoldr value)
201 , benchIOSrc "writeN . fromList" (sourceFromList value)
202 , benchIOSrc "write . intFromTo" (sourceIntFromToFromStream value)
206o_1_space_elimination :: Int -> [Benchmark]
207o_1_space_elimination value =
208 [ bgroup "elimination"
209 [ benchPureSink value "id" id
210 , benchIOSink value "foldl'" unfoldFold
211 , benchIOSink value "read" unfoldReadDrain
212 , benchIOSink value "readRev" unfoldReadRevDrain
213 , benchIOSink value "toStream" toStreamDDrain
214 , benchIOSink value "toStreamRev" toStreamDRevDrain
218o_n_heap_serial :: Int -> [Benchmark]
219o_n_heap_serial value =
220 [ bgroup "elimination"
222 -- Converting the stream to an array
223 benchFold "writeN" (Stream.fold (MArray.writeN value))
224 (sourceUnfoldrM value)
228o_1_space_transformation :: Int -> [Benchmark]
229o_1_space_transformation value =
230 [ bgroup "transformation"
231 [ benchIOSink value "scanl'" (scanl' value 1)
232 , benchIOSink value "scanl1'" (scanl1' value 1)
233 , benchIOSink value "map" (map value 1)
237o_1_space_transformationX4 :: Int -> [Benchmark]
238o_1_space_transformationX4 value =
239 [ bgroup "transformationX4"
240 [ benchIOSink value "scanl'" (scanl' value 4)
241 , benchIOSink value "scanl1'" (scanl1' value 4)
242 , benchIOSink value "map" (map value 4)
246o_1_space_serial_marray ::
247 Int -> (MArray.Array Int, Array.Array Int) -> [Benchmark]
248o_1_space_serial_marray value ~(array, indices) =
249 [ benchIO' "partitionBy (< 0)" (const (return array))
250 $ MArray.partitionBy (< 0)
251 , benchIO' "partitionBy (> 0)" (const (return array))
252 $ MArray.partitionBy (> 0)
253 , benchIO' "partitionBy (< value/2)" (const (return array))
254 $ MArray.partitionBy (< (value `div` 2))
255 , benchIO' "partitionBy (> value/2)" (const (return array))
256 $ MArray.partitionBy (> (value `div` 2))
257 , benchIO' "strip (< value/2 || > value/2)" (const (return array))
258 $ MArray.strip (\x -> x < value `div` 2 || x > value `div` 2)
259 , benchIO' "strip (> 0)" (const (return array))
261 , benchIO' "modifyIndices (+ 1)" (const (return indices))
262 $ Stream.fold (MArray.modifyIndices (\_idx val -> val + 1) array)
263 . Stream.unfold Array.read
266-------------------------------------------------------------------------------
268-------------------------------------------------------------------------------
271moduleName = "Data.Array.Unboxed.Mut"
275 runWithCLIOptsEnv defaultStreamSize alloc allBenchmarks
280 marr <- MArray.fromStream (sourceUnfoldrM value 0 :: Stream.Stream IO Int)
281 indices <- Array.fromStream (sourceUnfoldrM value 0 :: Stream.Stream IO Int)
282 return (marr, indices)
284 allBenchmarks array value =
285 [ bgroup (o_1_space_prefix moduleName)
287 [ o_1_space_serial_marray value array
288 , o_1_space_generation value
289 , o_1_space_elimination value
290 , o_1_space_transformation value
291 , o_1_space_transformationX4 value
293 , 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