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)
46import qualified Streamly.Internal.Data.Array as Array
47import qualified Streamly.Internal.Data.Array.Mut as MArray
48import qualified Streamly.Internal.Data.Fold as Fold
49import qualified Streamly.Internal.Data.Stream as Stream
50import qualified Streamly.Prelude as IsStream (scanl1')
53import Streamly.Benchmark.Common hiding (benchPureSrc)
55type Stream = MArray.Array
57instance NFData (MArray.Array 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 $ IsStream.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 ()
185 drain . Stream.fromStreamD . MArray.toStreamDRev
187{-# INLINE toStreamDDrain #-}
188toStreamDDrain :: MonadIO m => Stream Int -> m ()
189toStreamDDrain = drain . Stream.fromStreamD . MArray.toStreamD
191{-# INLINE unfoldFold #-}
192unfoldFold :: MonadIO m => Stream Int -> m Int
193unfoldFold = Stream.fold (Fold.foldl' (+) 0) . Stream.unfold MArray.reader
195-------------------------------------------------------------------------------
197-------------------------------------------------------------------------------
199o_1_space_generation :: Int -> [Benchmark]
200o_1_space_generation value =
203 [ benchIOSrc "writeN . intFromTo" (sourceIntFromTo value)
205 "fromList . intFromTo"
206 (sourceIntFromToFromList value)
207 , benchIOSrc "writeN . unfoldr" (sourceUnfoldr value)
208 , benchIOSrc "writeN . fromList" (sourceFromList value)
209 , benchIOSrc "write . intFromTo" (sourceIntFromToFromStream value)
213o_1_space_elimination :: Int -> [Benchmark]
214o_1_space_elimination value =
215 [ bgroup "elimination"
216 [ benchPureSink value "id" id
217 , benchIOSink value "foldl'" unfoldFold
218 , benchIOSink value "read" unfoldReadDrain
219 , benchIOSink value "readRev" unfoldReadRevDrain
220 , benchIOSink value "toStream" toStreamDDrain
221 , benchIOSink value "toStreamRev" toStreamDRevDrain
225o_n_heap_serial :: Int -> [Benchmark]
226o_n_heap_serial value =
227 [ bgroup "elimination"
229 -- Converting the stream to an array
230 benchFold "writeN" (Stream.fold (MArray.writeN value))
231 (sourceUnfoldrM value)
235o_1_space_transformation :: Int -> [Benchmark]
236o_1_space_transformation value =
237 [ bgroup "transformation"
238 [ benchIOSink value "scanl'" (scanl' value 1)
239 , benchIOSink value "scanl1'" (scanl1' value 1)
240 , benchIOSink value "map" (map value 1)
244o_1_space_transformationX4 :: Int -> [Benchmark]
245o_1_space_transformationX4 value =
246 [ bgroup "transformationX4"
247 [ benchIOSink value "scanl'" (scanl' value 4)
248 , benchIOSink value "scanl1'" (scanl1' value 4)
249 , benchIOSink value "map" (map value 4)
253o_1_space_serial_marray ::
254 Int -> (MArray.Array Int, Array.Array Int) -> [Benchmark]
255o_1_space_serial_marray value ~(array, indices) =
256 [ benchIO' "partitionBy (< 0)" (const (return array))
257 $ MArray.partitionBy (< 0)
258 , benchIO' "partitionBy (> 0)" (const (return array))
259 $ MArray.partitionBy (> 0)
260 , benchIO' "partitionBy (< value/2)" (const (return array))
261 $ MArray.partitionBy (< (value `div` 2))
262 , benchIO' "partitionBy (> value/2)" (const (return array))
263 $ MArray.partitionBy (> (value `div` 2))
264 , benchIO' "strip (< value/2 || > value/2)" (const (return array))
265 $ MArray.strip (\x -> x < value `div` 2 || x > value `div` 2)
266 , benchIO' "strip (> 0)" (const (return array))
268 , benchIO' "modifyIndices (+ 1)" (const (return indices))
269 $ Stream.fold (MArray.modifyIndices array (\_idx val -> val + 1))
270 . Stream.unfold Array.reader
273-------------------------------------------------------------------------------
275-------------------------------------------------------------------------------
278moduleName = "Data.Array.Mut"
282 runWithCLIOptsEnv defaultStreamSize alloc allBenchmarks
287 marr <- MArray.fromStream (sourceUnfoldrM value 0 :: Stream.Stream IO Int)
288 indices <- Array.fromStream (sourceUnfoldrM value 0 :: Stream.Stream IO Int)
289 return (marr, indices)
291 allBenchmarks array value =
292 [ bgroup (o_1_space_prefix moduleName)
294 [ o_1_space_serial_marray value array
295 , o_1_space_generation value
296 , o_1_space_elimination value
297 , o_1_space_transformation value
298 , o_1_space_transformationX4 value
300 , 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