1{-# OPTIONS_GHC -Wno-deprecations #-}
4-- Module : Streamly.Benchmark.Data.Stream.StreamDK
5-- Copyright : (c) 2018 Composewell Technologies
8-- Maintainer : streamly@composewell.com
10{-# LANGUAGE FlexibleContexts #-}
11{-# LANGUAGE ScopedTypeVariables #-}
13module Main (main) where
15-- import Control.Monad (when)
16-- import Data.Maybe (isJust)
17import Prelude hiding ()
18-- import qualified Prelude as P
19-- import qualified Data.List as List
21import qualified Streamly.Internal.Data.StreamK.Alt as S
22-- import qualified Streamly.Internal.Data.Stream.Common as SP
23-- import qualified Streamly.Internal.Data.SVar as S
25import Streamly.Benchmark.Common
26import Gauge (bgroup, Benchmark, defaultMain)
31value2, value3, value16, maxValue :: Int
32value2 = round (P.fromIntegral value**(1/2::P.Double)) -- double nested loop
33value3 = round (P.fromIntegral value**(1/3::P.Double)) -- triple nested loop
34value16 = round (P.fromIntegral value**(1/16::P.Double)) -- triple nested loop
38-------------------------------------------------------------------------------
40-------------------------------------------------------------------------------
42-------------------------------------------------------------------------------
43-- Stream generation and elimination
44-------------------------------------------------------------------------------
46type Stream m a = S.Stream m a
48{-# INLINE sourceUnfoldr #-}
49sourceUnfoldr :: Monad m => Int -> Stream m Int
50sourceUnfoldr n = S.unfoldr step n
55 else Just (cnt, cnt + 1)
58{-# INLINE sourceUnfoldrN #-}
59sourceUnfoldrN :: Monad m => Int -> Int -> Stream m Int
60sourceUnfoldrN m n = S.unfoldr step n
65 else Just (cnt, cnt + 1)
68{-# INLINE sourceUnfoldrM #-}
69sourceUnfoldrM :: Monad m => Int -> Stream m Int
70sourceUnfoldrM n = S.unfoldrM step n
75 else return (Just (cnt, cnt + 1))
78{-# INLINE sourceUnfoldrMN #-}
79sourceUnfoldrMN :: Monad m => Int -> Int -> Stream m Int
80sourceUnfoldrMN m n = S.unfoldrM step n
85 else return (Just (cnt, cnt + 1))
89{-# INLINE sourceFromEnum #-}
90sourceFromEnum :: Monad m => Int -> Stream m Int
91sourceFromEnum n = S.enumFromStepN n 1 value
95{-# INLINE sourceFromFoldable #-}
96sourceFromFoldable :: Int -> Stream m Int
97sourceFromFoldable n = S.fromFoldable [n..n+value]
101{-# INLINE sourceFromFoldableM #-}
102sourceFromFoldableM :: S.MonadAsync m => Int -> Stream m Int
103sourceFromFoldableM n = S.fromFoldableM (Prelude.fmap return [n..n+value])
107{-# INLINE sourceFoldMapWith #-}
108sourceFoldMapWith :: Int -> Stream m Int
109sourceFoldMapWith n = SP.foldMapWith S.serial S.fromPure [n..n+value]
111{-# INLINE sourceFoldMapWithM #-}
112sourceFoldMapWithM :: Monad m => Int -> Stream m Int
113sourceFoldMapWithM n = SP.foldMapWith S.serial (S.fromEffect . return) [n..n+value]
116-------------------------------------------------------------------------------
118-------------------------------------------------------------------------------
120{-# INLINE runStream #-}
121runStream :: Monad m => Stream m a -> m ()
123-- runStream = S.mapM_ (\_ -> return ())
127mapM_ :: Monad m => Stream m a -> m ()
128mapM_ = S.mapM_ (\_ -> return ())
132toNull :: Monad m => Stream m Int -> m ()
136uncons :: Monad m => Stream m Int -> m ()
141 Just (_, t) -> uncons t
145init :: (Monad m, S.IsStream t) => t m a -> m ()
151tail :: (Monad m, S.IsStream t) => t m a -> m ()
152tail s = S.tail s >>= P.mapM_ tail
154{-# INLINE nullTail #-}
155{-# INLINE headTail #-}
157nullTail, headTail, zip
159 => Stream m Int -> m ()
163 when (not r) $ S.tail s >>= P.mapM_ nullTail
167 when (isJust h) $ S.tail s >>= P.mapM_ headTail
170toList :: Monad m => Stream m Int -> m [Int]
174foldl :: Monad m => Stream m Int -> m Int
175foldl = S.foldl' (+) 0
178last :: Monad m => Stream m Int -> m (Maybe Int)
182-------------------------------------------------------------------------------
184-------------------------------------------------------------------------------
187{-# INLINE transform #-}
188transform :: Monad m => Stream m a -> m ()
191{-# INLINE composeN #-}
194 => Int -> (Stream m Int -> Stream m Int) -> Stream m Int -> m ()
198 2 -> transform . f . f
199 3 -> transform . f . f . f
200 4 -> transform . f . f . f . f
208{-# INLINE filterEven #-}
209{-# INLINE filterAllOut #-}
210{-# INLINE filterAllIn #-}
211{-# INLINE takeOne #-}
212{-# INLINE takeAll #-}
213{-# INLINE takeWhileTrue #-}
214{-# INLINE dropOne #-}
215{-# INLINE dropAll #-}
216{-# INLINE dropWhileTrue #-}
217{-# INLINE dropWhileFalse #-}
219{-# INLINE concatMap #-}
220scan, map, fmap, filterEven, filterAllOut,
221 filterAllIn, takeOne, takeAll, takeWhileTrue, dropAll, dropOne,
222 dropWhileTrue, dropWhileFalse, foldlS, concatMap
224 => Int -> Stream m Int -> m ()
227{-# INLINE mapMSerial #-}
228{-# INLINE intersperse #-}
229mapM, mapMSerial, intersperse
230 :: S.MonadAsync m => Int -> Stream m Int -> m ()
232scan n = composeN n $ S.scanl' (+) 0
233map n = composeN n $ P.fmap (+1)
234fmap n = composeN n $ P.fmap (+1)
235mapM n = composeN n $ S.mapM return
236mapMSerial n = composeN n $ S.mapMSerial return
237filterEven n = composeN n $ S.filter even
238filterAllOut n = composeN n $ S.filter (> maxValue)
239filterAllIn n = composeN n $ S.filter (<= maxValue)
240takeOne n = composeN n $ S.take 1
241takeAll n = composeN n $ S.take maxValue
242takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
243dropOne n = composeN n $ S.drop 1
244dropAll n = composeN n $ S.drop maxValue
245dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
246dropWhileFalse n = composeN n $ S.dropWhile (<= 1)
247foldlS n = composeN n $ S.foldlS (flip S.cons) S.nil
248-- We use a (sqrt n) element stream as source and then concat the same stream
249-- for each element to produce an n element stream.
250concatMap n = composeN n $ (\s -> S.concatMap (\_ -> s) s)
251intersperse n = composeN n $ S.intersperse maxValue
253-------------------------------------------------------------------------------
255-------------------------------------------------------------------------------
257iterStreamLen, maxIters :: Int
261{-# INLINE iterateSource #-}
264 => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
265iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
268 f x m = g (f (x P.- 1) m)
270{-# INLINE iterateMapM #-}
271{-# INLINE iterateScan #-}
272{-# INLINE iterateFilterEven #-}
273{-# INLINE iterateTakeAll #-}
274{-# INLINE iterateDropOne #-}
275{-# INLINE iterateDropWhileFalse #-}
276{-# INLINE iterateDropWhileTrue #-}
277iterateMapM, iterateScan, iterateFilterEven, iterateTakeAll, iterateDropOne,
278 iterateDropWhileFalse, iterateDropWhileTrue
280 => Int -> Stream m Int
283iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
284iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue))
287iterateMapM = iterateSource (S.mapM return) maxIters
288iterateFilterEven = iterateSource (S.filter even) maxIters
289iterateTakeAll = iterateSource (S.take maxValue) maxIters
290iterateDropOne = iterateSource (S.drop 1) maxIters
291iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
293-------------------------------------------------------------------------------
295-------------------------------------------------------------------------------
297zip src = transform $ S.zipWith (,) src src
299{-# INLINE concatMapRepl4xN #-}
300concatMapRepl4xN :: Monad m => Stream m Int -> m ()
301concatMapRepl4xN src = transform $ (S.concatMap (S.replicate 4) src)
303-------------------------------------------------------------------------------
305-------------------------------------------------------------------------------
307{-# INLINE scanMap #-}
308{-# INLINE dropMap #-}
309{-# INLINE dropScan #-}
310{-# INLINE takeDrop #-}
311{-# INLINE takeScan #-}
312{-# INLINE takeMap #-}
313{-# INLINE filterDrop #-}
314{-# INLINE filterTake #-}
315{-# INLINE filterScan #-}
316{-# INLINE filterMap #-}
317scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
318 filterTake, filterScan, filterMap
319 :: Monad m => Int -> Stream m Int -> m ()
321scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
322dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
323dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
324takeDrop n = composeN n $ S.drop 1 . S.take maxValue
325takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
326takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
327filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
328filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
329filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
330filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
332-------------------------------------------------------------------------------
334-------------------------------------------------------------------------------
336{-# INLINE toNullApNested #-}
337toNullApNested :: Monad m => Stream m Int -> m ()
338toNullApNested s = runStream $ do
341{-# INLINE toNullNested #-}
342toNullNested :: Monad m => Stream m Int -> m ()
343toNullNested s = runStream $ do
348{-# INLINE toNullNested3 #-}
349toNullNested3 :: Monad m => Stream m Int -> m ()
350toNullNested3 s = runStream $ do
356{-# INLINE filterAllOutNested #-}
359 => Stream m Int -> m ()
360filterAllOutNested str = runStream $ do
368{-# INLINE filterAllInNested #-}
371 => Stream m Int -> m ()
372filterAllInNested str = runStream $ do
380-------------------------------------------------------------------------------
381-- Nested Composition Pure lists
382-------------------------------------------------------------------------------
384{-# INLINE sourceUnfoldrList #-}
385sourceUnfoldrList :: Int -> Int -> [Int]
386sourceUnfoldrList maxval n = List.unfoldr step n
391 else Just (cnt, cnt + 1)
393{-# INLINE toNullApNestedList #-}
394toNullApNestedList :: [Int] -> [Int]
395toNullApNestedList s = (+) <$> s <*> s
397{-# INLINE toNullNestedList #-}
398toNullNestedList :: [Int] -> [Int]
399toNullNestedList s = do
404{-# INLINE toNullNestedList3 #-}
405toNullNestedList3 :: [Int] -> [Int]
406toNullNestedList3 s = do
412{-# INLINE filterAllOutNestedList #-}
413filterAllOutNestedList :: [Int] -> [Int]
414filterAllOutNestedList str = do
422{-# INLINE filterAllInNestedList #-}
423filterAllInNestedList :: [Int] -> [Int]
424filterAllInNestedList str = do
433-------------------------------------------------------------------------------
435-------------------------------------------------------------------------------
438moduleName = "Data.Stream.StreamDK"
440o_1_space :: [Benchmark]
442 [ bgroup (o_1_space_prefix moduleName)
443 [ bgroup "generation"
444 [ benchFold "unfoldr" toNull sourceUnfoldr
445 , benchFold "unfoldrM" toNull sourceUnfoldrM
447 , bgroup "elimination"
448 [ benchFold "toNull" toNull sourceUnfoldrM
449 , benchFold "uncons" uncons sourceUnfoldrM
455main = 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