3-- Copyright : (c) 2018 Composewell Technologies
6-- Maintainer : streamly@composewell.com
8{-# LANGUAGE FlexibleContexts #-}
10import Prelude hiding (mapM)
12import Data.Function ((&))
13import Streamly.Prelude
14 ( SerialT, parallely, parallel, serially, maxBuffer, maxThreads)
16import qualified Streamly.Prelude as S
17import qualified Streamly.Internal.Data.Fold as FL
18import qualified Streamly.Internal.Data.Stream.Parallel as Par
19import qualified Streamly.Internal.Data.Stream.IsStream as Internal
21import Streamly.Benchmark.Common
22import Streamly.Benchmark.Prelude
27moduleName = "Prelude.Parallel"
29-------------------------------------------------------------------------------
31-------------------------------------------------------------------------------
33{-# INLINE mergeAsyncByM #-}
34mergeAsyncByM :: (S.IsStream t, S.MonadAsync m) => Int -> Int -> t m Int
35mergeAsyncByM count n =
37 (\a b -> return (a `compare` b))
38 (sourceUnfoldrM count n)
39 (sourceUnfoldrM count (n + 1))
41{-# INLINE mergeAsyncBy #-}
42mergeAsyncBy :: (S.IsStream t, S.MonadAsync m) => Int -> Int -> t m Int
46 (sourceUnfoldrM count n)
47 (sourceUnfoldrM count (n + 1))
49-------------------------------------------------------------------------------
51-------------------------------------------------------------------------------
53{-# INLINE parAppMap #-}
54parAppMap :: S.MonadAsync m => SerialT m Int -> m ()
55parAppMap src = S.drain $ S.map (+1) S.|$ src
57{-# INLINE parAppSum #-}
58parAppSum :: S.MonadAsync m => SerialT m Int -> m ()
59parAppSum src = (S.sum S.|$. src) >>= \x -> seq x (return ())
62(|&) :: S.MonadAsync m => SerialT m Int -> m ()
63(|&) src = src S.|& S.map (+ 1) & S.drain
66(|&.) :: S.MonadAsync m => SerialT m Int -> m ()
67(|&.) src = (src S.|&. S.sum) >>= \x -> seq x (return ())
69-------------------------------------------------------------------------------
71-------------------------------------------------------------------------------
73{-# INLINE tapAsyncS #-}
74tapAsyncS :: S.MonadAsync m => Int -> SerialT m Int -> m ()
75tapAsyncS n = composeN n $ Par.tapAsync S.sum
77{-# INLINE tapAsync #-}
78tapAsync :: S.MonadAsync m => Int -> SerialT m Int -> m ()
79tapAsync n = composeN n $ Internal.tapAsync FL.sum
81o_1_space_merge_app_tap :: Int -> [Benchmark]
82o_1_space_merge_app_tap value =
83 [ bgroup "merge-app-tap"
84 [ benchIOSrc serially "mergeAsyncBy (2,x/2)"
85 (mergeAsyncBy (value `div` 2))
86 , benchIOSrc serially "mergeAsyncByM (2,x/2)"
87 (mergeAsyncByM (value `div` 2))
88 -- Parallel stages in a pipeline
89 , benchIOSink value "parAppMap" parAppMap
90 , benchIOSink value "parAppSum" parAppSum
91 , benchIOSink value "(|&)" (|&)
92 , benchIOSink value "(|&.)" (|&.)
93 , benchIOSink value "tapAsync" (tapAsync 1)
94 , benchIOSink value "tapAsyncS" (tapAsyncS 1)
98-------------------------------------------------------------------------------
100-------------------------------------------------------------------------------
102o_n_heap_generation :: Int -> [Benchmark]
103o_n_heap_generation value =
106 [ benchIOSrc parallely "unfoldr" (sourceUnfoldr value)
107 , benchIOSrc parallely "unfoldrM" (sourceUnfoldrM value)
108 , benchIOSrc parallely "fromFoldable" (sourceFromFoldable value)
109 , benchIOSrc parallely "fromFoldableM" (sourceFromFoldableM value)
110 , benchIOSrc parallely "unfoldrM maxThreads 1"
111 (maxThreads 1 . sourceUnfoldrM value)
112 , benchIOSrc parallely "unfoldrM maxBuffer 1 (x/10 ops)"
113 (maxBuffer 1 . sourceUnfoldrM (value `div` 10))
117-------------------------------------------------------------------------------
119-------------------------------------------------------------------------------
121o_n_heap_mapping :: Int -> [Benchmark]
122o_n_heap_mapping value =
124 [ benchIOSink value "map" $ mapN parallely 1
125 , benchIOSink value "fmap" $ fmapN parallely 1
126 , benchIOSink value "mapM" $ mapM parallely 1 . serially
131-------------------------------------------------------------------------------
133-------------------------------------------------------------------------------
135{-# INLINE parallel2 #-}
136parallel2 :: Int -> Int -> IO ()
139 (sourceUnfoldrM count n) `parallel` (sourceUnfoldrM count (n + 1))
141o_1_space_joining :: Int -> [Benchmark]
142o_1_space_joining value =
144 [ benchIOSrc1 "parallel (2 of n/2)" (parallel2 (value `div` 2))
148-------------------------------------------------------------------------------
150-------------------------------------------------------------------------------
152o_n_heap_concatFoldable :: Int -> [Benchmark]
153o_n_heap_concatFoldable value =
156 [ benchIOSrc parallely "foldMapWith (<>) (List)"
157 (sourceFoldMapWith value)
158 , benchIOSrc parallely "foldMapWith (<>) (Stream)"
159 (sourceFoldMapWithStream value)
160 , benchIOSrc parallely "foldMapWithM (<>) (List)"
161 (sourceFoldMapWithM value)
162 , benchIOSrc serially "S.concatFoldableWith (<>) (List)"
163 (concatFoldableWith value)
164 , benchIOSrc serially "S.concatForFoldableWith (<>) (List)"
165 (concatForFoldableWith value)
166 , benchIOSrc parallely "foldMapM (List)" (sourceFoldMapM value)
170o_n_heap_concat :: Int -> [Benchmark]
171o_n_heap_concat value =
174 -- This is for comparison with foldMapWith
175 [ benchIOSrc serially "concatMapWithId (n of 1) (fromFoldable)"
176 (S.concatMapWith parallel id . sourceConcatMapId value)
178 , benchIO "concatMapWith (n of 1)"
179 (concatStreamsWith parallel value 1)
180 , benchIO "concatMapWith (sqrt x of sqrt x)"
181 (concatStreamsWith parallel value2 value2)
182 , benchIO "concatMapWith (1 of n)"
183 (concatStreamsWith parallel 1 value)
189 value2 = round $ sqrt (fromIntegral value :: Double)
191-------------------------------------------------------------------------------
192-- Monadic outer product
193-------------------------------------------------------------------------------
195o_n_heap_outerProduct :: Int -> [Benchmark]
196o_n_heap_outerProduct value =
197 [ bgroup "monad-outer-product"
198 [ benchIO "toNullAp" $ toNullAp value parallely
199 , benchIO "toNull" $ toNullM value parallely
200 , benchIO "toNull3" $ toNullM3 value parallely
201 , benchIO "filterAllOut" $ filterAllOutM value parallely
202 , benchIO "filterAllIn" $ filterAllInM value parallely
203 , benchIO "filterSome" $ filterSome value parallely
204 , benchIO "breakAfterSome" $ breakAfterSome value parallely
208o_n_space_outerProduct :: Int -> [Benchmark]
209o_n_space_outerProduct value =
210 [ bgroup "monad-outer-product"
211 [ benchIO "toList" $ toListM value parallely
212 -- XXX disabled due to a bug for now
213 -- , benchIO "toListSome" $ toListSome value parallely
217-------------------------------------------------------------------------------
219-------------------------------------------------------------------------------
223 (value, cfg, benches) <- parseCLIOpts defaultStreamSize
224 value `seq` runMode (mode cfg) cfg benches (allBenchmarks value)
228 allBenchmarks value =
229 [ bgroup (o_1_space_prefix moduleName) $ concat
230 [ o_1_space_merge_app_tap value
231 , o_1_space_joining value
233 , bgroup (o_n_heap_prefix moduleName) $ concat
234 [ o_n_heap_generation value
235 , o_n_heap_mapping value
236 , o_n_heap_concatFoldable value
237 , o_n_heap_concat value
238 , o_n_heap_outerProduct value
240 , bgroup (o_n_space_prefix moduleName) (o_n_space_outerProduct 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