on master help sign in
Add a middle point for concatMapWith benchmark

* We are testing two extreme cases, add a middle case as well where the outer and inner streams are of equal size. * Enable some pure benchmarks as well * Separate the zip benchmarks in a separate group as they are scalable (memory consumption does not increase with stream size) and parallel benchmarks are not scalable.

commit22bfa7259975d9e2a5ea82cc59947a294fd2c81b authorHarendra Kumar <harendra.kumar@gmail.com> dateThu 16 Jan 2020, 15:58 (7 years ago) parentafc02e6
2 files changed+39−14
benchmark/LinearAsync.hs+37−12 benchmark/Streamly/Benchmark/Prelude.hs+2−2
benchmark/LinearAsync.hs+37−12
@@ -51,7 +51,8 @@ main :: IO ()
5151main = do
5252 -- XXX Fix indentation
5353 (value, cfg, benches) <- parseCLIOpts defaultStreamSize
54− value `seq` runMode (mode cfg) cfg benches
54+ let value2 = round $ sqrt $ (fromIntegral value :: Double)
55+ value2 `seq` value `seq` runMode (mode cfg) cfg benches
5556 [ bgroup "asyncly"
5657 [ benchSrcIO asyncly "unfoldr" (Ops.sourceUnfoldr value)
5758 , benchSrcIO asyncly "unfoldrM" (Ops.sourceUnfoldrM value)
@@ -69,6 +70,8 @@ main = do
6970 (maxBuffer 1 . Ops.sourceUnfoldrMN (value `div` 10))
7071 , benchMonadicSrcIO "concatMapWith (2,x/2)"
7172 (Ops.concatStreamsWith async 2 (value `div` 2))
73+ , benchMonadicSrcIO "concatMapWith (sqrt x,sqrt x)"
74+ (Ops.concatStreamsWith async value2 value2)
7275 , benchMonadicSrcIO "concatMapWith (x/2,2)"
7376 (Ops.concatStreamsWith async (value `div` 2) 2)
7477 ]
@@ -83,8 +86,22 @@ main = do
8386 , benchIO value "map" $ Ops.map' wAsyncly 1
8487 , benchIO value "fmap" $ Ops.fmap' wAsyncly 1
8588 , benchIO value "mapM" $ Ops.mapM wAsyncly 1
89+ , benchSrcIO wAsyncly "unfoldrM maxThreads 1"
90+ (maxThreads 1 . Ops.sourceUnfoldrM value)
91+ , benchSrcIO wAsyncly "unfoldrM maxBuffer 1 (x/10 ops)"
92+ (maxBuffer 1 . Ops.sourceUnfoldrMN (value `div` 10))
93+ -- When we merge streams using wAsync the size of the queue increases
94+ -- slowly because of the binary composition adding just one more item
95+ -- to the work queue only after every scheduling pass through the
96+ -- work queue.
97+ --
98+ -- We should see the memory consumption increasing slowly if these
99+ -- benchmarks are left to run on infinite number of streams of infinite
100+ -- sizes.
86101 , benchMonadicSrcIO "concatMapWith (2,x/2)"
87102 (Ops.concatStreamsWith wAsync 2 (value `div` 2))
103+ , benchMonadicSrcIO "concatMapWith (sqrt x,sqrt x)"
104+ (Ops.concatStreamsWith wAsync value2 value2)
88105 , benchMonadicSrcIO "concatMapWith (x/2,2)"
89106 (Ops.concatStreamsWith wAsync (value `div` 2) 2)
90107 ]
@@ -94,7 +111,7 @@ main = do
94111 [ benchSrcIO aheadly "unfoldr" (Ops.sourceUnfoldr value)
95112 , benchSrcIO aheadly "unfoldrM" (Ops.sourceUnfoldrM value)
96113 , benchSrcIO aheadly "fromFoldableM" (Ops.sourceFromFoldableM value)
97− -- , benchSrcIO aheadly "foldMapWith" Ops.sourceFoldMapWith
114+ , benchSrcIO aheadly "foldMapWith" (Ops.sourceFoldMapWith value)
98115 , benchSrcIO aheadly "foldMapWithM" (Ops.sourceFoldMapWithM value)
99116 , benchSrcIO aheadly "foldMapM" (Ops.sourceFoldMapM value)
100117 , benchIO value "map" $ Ops.map' aheadly 1
@@ -104,35 +121,43 @@ main = do
104121 (maxThreads 1 . Ops.sourceUnfoldrM value)
105122 , benchSrcIO aheadly "unfoldrM maxBuffer 1 (x/10 ops)"
106123 (maxBuffer 1 . Ops.sourceUnfoldrMN (value `div` 10))
107− -- , benchSrcIO aheadly "fromFoldable" Ops.sourceFromFoldable
124+ , benchSrcIO aheadly "fromFoldable" (Ops.sourceFromFoldable value)
108125 , benchMonadicSrcIO "concatMapWith (2,x/2)"
109126 (Ops.concatStreamsWith ahead 2 (value `div` 2))
127+ , benchMonadicSrcIO "concatMapWith (sqrt x,sqrt x)"
128+ (Ops.concatStreamsWith ahead value2 value2)
110129 , benchMonadicSrcIO "concatMapWith (x/2,2)"
111130 (Ops.concatStreamsWith ahead (value `div` 2) 2)
112131 ]
113132 -- XXX need to use smaller streams to finish in reasonable time
114133 , bgroup "parallely"
115− [ benchSrcIO parallely "unfoldr" (Ops.sourceUnfoldr value)
134+ [ -- unfoldr is pure and works serially irrespective of the stream type
135+ benchSrcIO parallely "unfoldr" (Ops.sourceUnfoldr value)
116136 , benchSrcIO parallely "unfoldrM" (Ops.sourceUnfoldrM value)
117− --, benchSrcIO parallely "fromFoldable" Ops.sourceFromFoldable
137+ , benchSrcIO parallely "fromFoldable" (Ops.sourceFromFoldable value)
118138 , benchSrcIO parallely "fromFoldableM" (Ops.sourceFromFoldableM value)
119− -- , benchSrcIO parallely "foldMapWith" Ops.sourceFoldMapWith
139+ , benchSrcIO parallely "foldMapWith" (Ops.sourceFoldMapWith value)
120140 , benchSrcIO parallely "foldMapWithM" (Ops.sourceFoldMapWithM value)
121141 , benchSrcIO parallely "foldMapM" (Ops.sourceFoldMapM value)
142+ -- map/fmap are pure and therefore no concurrency would be added on top
143+ -- of what the source stream (i.e. unfoldrM) provides.
122144 , benchIO value "map" $ Ops.map' parallely 1
123145 , benchIO value "fmap" $ Ops.fmap' parallely 1
124146 , benchIO value "mapM" $ Ops.mapM parallely 1
125− -- Zip has only one parallel flavor
126− , benchIO value "zip" Ops.zipAsync
147+ , benchMonadicSrcIO "concatMapWith (2,x/2)"
148+ (Ops.concatStreamsWith parallel 2 (value `div` 2))
149+ , benchMonadicSrcIO "concatMapWith (sqrt x,sqrt x)"
150+ (Ops.concatStreamsWith parallel value2 value2)
151+ , benchMonadicSrcIO "concatMapWith (x/2,2)"
152+ (Ops.concatStreamsWith parallel (value `div` 2) 2)
153+ ]
154+ , bgroup "zip"
155+ [ benchIO value "zip" Ops.zipAsync
127156 , benchIO value "zipM" Ops.zipAsyncM
128157 , benchIO value "zipAp" Ops.zipAsyncAp
129158 , benchIO value "fmap zipAsyncly" $ Ops.fmap' zipAsyncly 1
130159 -- Parallel stages in a pipeline
131160 , benchIO value "parAppMap" Ops.parAppMap
132161 , benchIO value "parAppSum" Ops.parAppSum
133− , benchMonadicSrcIO "concatMapWith (2,x/2)"
134− (Ops.concatStreamsWith parallel 2 (value `div` 2))
135− , benchMonadicSrcIO "concatMapWith (x/10,10)"
136− (Ops.concatStreamsWith parallel (value `div` 10) 10)
137162 ]
138163 ]
benchmark/Streamly/Benchmark/Prelude.hs+2−2
@@ -875,8 +875,8 @@ concatStreamsWith
875875 -> IO ()
876876concatStreamsWith op outer inner n =
877877 S.drain $ S.concatMapWith op
878− (\_ -> sourceUnfoldrMN inner n)
879− (sourceUnfoldrMN outer n)
878+ (\i -> sourceUnfoldrMN (i + inner) i)
879+ (sourceUnfoldrMN (n + outer) n)
880880
881881{-# INLINE concatMapWithSerial #-}
882882concatMapWithSerial :: Int -> Int -> Int -> IO ()