2-- Module : Streamly.Benchmark.Data.Stream.StreamDK
3-- Copyright : (c) 2018 Composewell Technologies
6-- Maintainer : streamly@composewell.com
8{-# LANGUAGE FlexibleContexts #-}
9{-# LANGUAGE ScopedTypeVariables #-}
11module Main (main) where
13-- import Control.Monad (when)
14-- import Data.Maybe (isJust)
15import Prelude hiding ()
16-- import qualified Prelude as P
17-- import qualified Data.List as List
19import qualified Streamly.Internal.Data.Stream.StreamDK as S
20-- import qualified Streamly.Internal.Data.Stream.Common as SP
21-- import qualified Streamly.Internal.Data.SVar as S
23import Streamly.Benchmark.Common
24import Gauge (bgroup, Benchmark, defaultMain)
29value2, value3, value16, maxValue :: Int
30value2 = round (P.fromIntegral value**(1/2::P.Double)) -- double nested loop
31value3 = round (P.fromIntegral value**(1/3::P.Double)) -- triple nested loop
32value16 = round (P.fromIntegral value**(1/16::P.Double)) -- triple nested loop
36-------------------------------------------------------------------------------
38-------------------------------------------------------------------------------
40-------------------------------------------------------------------------------
41-- Stream generation and elimination
42-------------------------------------------------------------------------------
44type Stream m a = S.Stream m a
46{-# INLINE sourceUnfoldr #-}
47sourceUnfoldr :: Monad m => Int -> Stream m Int
48sourceUnfoldr n = S.unfoldr step n
53 else Just (cnt, cnt + 1)
56{-# INLINE sourceUnfoldrN #-}
57sourceUnfoldrN :: Monad m => Int -> Int -> Stream m Int
58sourceUnfoldrN m n = S.unfoldr step n
63 else Just (cnt, cnt + 1)
66{-# INLINE sourceUnfoldrM #-}
67sourceUnfoldrM :: Monad m => Int -> Stream m Int
68sourceUnfoldrM n = S.unfoldrM step n
73 else return (Just (cnt, cnt + 1))
76{-# INLINE sourceUnfoldrMN #-}
77sourceUnfoldrMN :: Monad m => Int -> Int -> Stream m Int
78sourceUnfoldrMN m n = S.unfoldrM step n
83 else return (Just (cnt, cnt + 1))
87{-# INLINE sourceFromEnum #-}
88sourceFromEnum :: Monad m => Int -> Stream m Int
89sourceFromEnum n = S.enumFromStepN n 1 value
93{-# INLINE sourceFromFoldable #-}
94sourceFromFoldable :: Int -> Stream m Int
95sourceFromFoldable n = S.fromFoldable [n..n+value]
99{-# INLINE sourceFromFoldableM #-}
100sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
101sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
105{-# INLINE sourceFoldMapWith #-}
106sourceFoldMapWith :: Int -> Stream m Int
107sourceFoldMapWith n = SP.foldMapWith S.serial S.fromPure [n..n+value]
109{-# INLINE sourceFoldMapWithM #-}
110sourceFoldMapWithM :: Monad m => Int -> Stream m Int
111sourceFoldMapWithM n = SP.foldMapWith S.serial (S.fromEffect . return) [n..n+value]
114-------------------------------------------------------------------------------
116-------------------------------------------------------------------------------
118{-# INLINE runStream #-}
119runStream :: Monad m => Stream m a -> m ()
121-- runStream = S.mapM_ (\_ -> return ())
125mapM_ :: Monad m => Stream m a -> m ()
126mapM_ = S.mapM_ (\_ -> return ())
130toNull :: Monad m => Stream m Int -> m ()
134uncons :: Monad m => Stream m Int -> m ()
139 Just (_, t) -> uncons t
143init :: (Monad m, S.IsStream t) => t m a -> m ()
149tail :: (Monad m, S.IsStream t) => t m a -> m ()
150tail s = S.tail s >>= P.mapM_ tail
152{-# INLINE nullTail #-}
153{-# INLINE headTail #-}
155nullTail, headTail, zip
157 => Stream m Int -> m ()
161 when (not r) $ S.tail s >>= P.mapM_ nullTail
165 when (isJust h) $ S.tail s >>= P.mapM_ headTail
168toList :: Monad m => Stream m Int -> m [Int]
172foldl :: Monad m => Stream m Int -> m Int
173foldl = S.foldl' (+) 0
176last :: Monad m => Stream m Int -> m (Maybe Int)
180-------------------------------------------------------------------------------
182-------------------------------------------------------------------------------
185{-# INLINE transform #-}
186transform :: Monad m => Stream m a -> m ()
189{-# INLINE composeN #-}
192 => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
196 2 -> transform . f . f
197 3 -> transform . f . f . f
198 4 -> transform . f . f . f . f
206{-# INLINE filterEven #-}
207{-# INLINE filterAllOut #-}
208{-# INLINE filterAllIn #-}
209{-# INLINE takeOne #-}
210{-# INLINE takeAll #-}
211{-# INLINE takeWhileTrue #-}
212{-# INLINE dropOne #-}
213{-# INLINE dropAll #-}
214{-# INLINE dropWhileTrue #-}
215{-# INLINE dropWhileFalse #-}
217{-# INLINE concatMap #-}
218scan, map, fmap, filterEven, filterAllOut,
219 filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropOne,
220 dropWhileTrue, dropWhileFalse, foldlS, concatMap
222 => Int -> Stream m Int -> m ()
225{-# INLINE mapMSerial #-}
226{-# INLINE intersperse #-}
227mapM, mapMSerial, intersperse
228 :: S.MonadAsync m => Int -> Stream m Int -> m ()
230scan n = composeN n $ S.scanl' (+) 0
231map n = composeN n $ P.fmap (+1)
232fmap n = composeN n $ P.fmap (+1)
233mapM n = composeN n $ S.mapM return
234mapMSerial n = composeN n $ S.mapMSerial return
235filterEven n = composeN n $ S.filter even
236filterAllOut n = composeN n $ S.filter (> maxValue)
237filterAllIn n = composeN n $ S.filter (<= maxValue)
238takeOne n = composeN n $ S.take 1
239takeAll n = composeN n $ S.take maxValue
240takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
241dropOne n = composeN n $ S.drop 1
242dropAll n = composeN n $ S.drop maxValue
243dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
244dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
245foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
246-- We use a (sqrt n) element stream as source and then concat the same stream
247-- for each element to produce an n element stream.
248concatMap n = composeN n $ (\s -> S.concatMap (\_ -> s) s)
249intersperse n = composeN n $ S.intersperse maxValue
251-------------------------------------------------------------------------------
253-------------------------------------------------------------------------------
255iterStreamLen, maxIters :: Int
259{-# INLINE iterateSource #-}
262 => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
263iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
266 f x m = g (f (x P.- 1) m)
268{-# INLINE iterateMapM #-}
269{-# INLINE iterateScan #-}
270{-# INLINE iterateFilterEven #-}
271{-# INLINE iterateTakeAll #-}
272{-# INLINE iterateDropOne #-}
273{-# INLINE iterateDropWhileFalse #-}
274{-# INLINE iterateDropWhileTrue #-}
275iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
276 iterateDropWhileFalse, iterateDropWhileTrue
278 => Int -> Stream m Int
281iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
282iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue))
285iterateMapM = iterateSource (S.mapM return) maxIters
286iterateFilterEven = iterateSource (S.filter even) maxIters
287iterateTakeAll = iterateSource (S.take maxValue) maxIters
288iterateDropOne = iterateSource (S.drop 1) maxIters
289iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
291-------------------------------------------------------------------------------
293-------------------------------------------------------------------------------
295zip src = transform $ S.zipWith (,) src src
297{-# INLINE concatMapRepl4xN #-}
298concatMapRepl4xN :: Monad m => Stream m Int -> m ()
299concatMapRepl4xN src = transform $ (S.concatMap (S.replicate 4) src)
301-------------------------------------------------------------------------------
303-------------------------------------------------------------------------------
305{-# INLINE scanMap #-}
306{-# INLINE dropMap #-}
307{-# INLINE dropScan #-}
308{-# INLINE takeDrop #-}
309{-# INLINE takeScan #-}
310{-# INLINE takeMap #-}
311{-# INLINE filterDrop #-}
312{-# INLINE filterTake #-}
313{-# INLINE filterScan #-}
314{-# INLINE filterMap #-}
315scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
316 filterTake, filterScan, filterMap
317 :: Monad m => Int -> Stream m Int -> m ()
319scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
320dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
321dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
322takeDrop n = composeN n $ S.drop 1 . S.take maxValue
323takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
324takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
325filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
326filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
327filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
328filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
330-------------------------------------------------------------------------------
332-------------------------------------------------------------------------------
334{-# INLINE toNullApNested #-}
335toNullApNested :: Monad m => Stream m Int -> m ()
336toNullApNested s = runStream $ do
339{-# INLINE toNullNested #-}
340toNullNested :: Monad m => Stream m Int -> m ()
341toNullNested s = runStream $ do
346{-# INLINE toNullNested3 #-}
347toNullNested3 :: Monad m => Stream m Int -> m ()
348toNullNested3 s = runStream $ do
354{-# INLINE filterAllOutNested #-}
357 => Stream m Int -> m ()
358filterAllOutNested str = runStream $ do
366{-# INLINE filterAllInNested #-}
369 => Stream m Int -> m ()
370filterAllInNested str = runStream $ do
378-------------------------------------------------------------------------------
379-- Nested Composition Pure lists
380-------------------------------------------------------------------------------
382{-# INLINE sourceUnfoldrList #-}
383sourceUnfoldrList :: Int -> Int -> [Int]
384sourceUnfoldrList maxval n = List.unfoldr step n
389 else Just (cnt, cnt + 1)
391{-# INLINE toNullApNestedList #-}
392toNullApNestedList :: [Int] -> [Int]
393toNullApNestedList s = (+) <$> s <*> s
395{-# INLINE toNullNestedList #-}
396toNullNestedList :: [Int] -> [Int]
397toNullNestedList s = do
402{-# INLINE toNullNestedList3 #-}
403toNullNestedList3 :: [Int] -> [Int]
404toNullNestedList3 s = do
410{-# INLINE filterAllOutNestedList #-}
411filterAllOutNestedList :: [Int] -> [Int]
412filterAllOutNestedList str = do
420{-# INLINE filterAllInNestedList #-}
421filterAllInNestedList :: [Int] -> [Int]
422filterAllInNestedList str = do
431-------------------------------------------------------------------------------
433-------------------------------------------------------------------------------
436moduleName = "Data.Stream.StreamDK"
438o_1_space :: [Benchmark]
440 [ bgroup (o_1_space_prefix moduleName)
441 [ bgroup "generation"
442 [ benchFold "unfoldr" toNull sourceUnfoldr
443 , benchFold "unfoldrM" toNull sourceUnfoldrM
445 , bgroup "elimination"
446 [ benchFold "toNull" toNull sourceUnfoldrM
447 , benchFold "uncons" uncons sourceUnfoldrM
453main = defaultMain $ concat [o_1_space]
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