on master help sign in
separate const mem benchmarks from buffered ones
afc02e6Harendra Kumar
benchmark/Linear.hs+64−42
@@ -143,17 +143,9 @@ main = do
143 -- length is used to check for foldr/build fusion
143 -- length is used to check for foldr/build fusion
144 , benchPureSink value "length . IsList.toList" (length . GHC.toList)
144 , benchPureSink value "length . IsList.toList" (length . GHC.toList)
145 , benchPureSrc "IsString.fromString" (Ops.sourceIsString value)
145 , benchPureSrc "IsString.fromString" (Ops.sourceIsString value)
146− , mkString value `deepseq` (bench "readsPrec pure streams" $
147− nf Ops.readInstance (mkString value))
148− , mkString value `deepseq` (bench "readsPrec Haskell lists" $
149− nf Ops.readInstanceList (mkListString value))
150 , benchPureSink value "showsPrec pure streams" Ops.showInstance
146 , benchPureSink value "showsPrec pure streams" Ops.showInstance
151− , mkList value `deepseq` (bench "showPrec Haskell lists" $
152− nf Ops.showInstanceList (mkList value))
153 , benchPureSink value "foldl'" Ops.pureFoldl'
147 , benchPureSink value "foldl'" Ops.pureFoldl'
154 , benchPureSink value "foldable/foldl'" Ops.foldableFoldl'
148 , benchPureSink value "foldable/foldl'" Ops.foldableFoldl'
155− , benchPureSink value "foldable/sum" Ops.foldableSum
156− , benchPureSinkIO value "traversable/mapM" Ops.traversableMapM
157 ]
149 ]
158 , bgroup "generation"
150 , bgroup "generation"
159 [ -- Most basic, barely stream continuations running
151 [ -- Most basic, barely stream continuations running
@@ -173,29 +165,22 @@ main = do
173 , bgroup "elimination"
165 , bgroup "elimination"
174 [ bgroup "reduce"
166 [ bgroup "reduce"
175 [ bgroup "IO"
167 [ bgroup "IO"
176− [ benchIOSink value "foldrM" Ops.foldrMReduce
168+ [
177− , benchIOSink value "foldl'" Ops.foldl'Reduce
169+ benchIOSink value "foldl'" Ops.foldl'Reduce
178 , benchIOSink value "foldl1'" Ops.foldl1'Reduce
170 , benchIOSink value "foldl1'" Ops.foldl1'Reduce
179 , benchIOSink value "foldlM'" Ops.foldlM'Reduce
171 , benchIOSink value "foldlM'" Ops.foldlM'Reduce
180 ]
172 ]
181 , bgroup "Identity"
173 , bgroup "Identity"
182− [ benchIdentitySink value "foldrM" Ops.foldrMReduce
174+ [
183− , benchIdentitySink value "foldl'" Ops.foldl'Reduce
175+ benchIdentitySink value "foldl'" Ops.foldl'Reduce
184 , benchIdentitySink value "foldl1'" Ops.foldl1'Reduce
176 , benchIdentitySink value "foldl1'" Ops.foldl1'Reduce
185 , benchIdentitySink value "foldlM'" Ops.foldlM'Reduce
177 , benchIdentitySink value "foldlM'" Ops.foldlM'Reduce
186 ]
178 ]
187 ]
179 ]
188
180
189 , bgroup "build"
181 , bgroup "build"
190− [ bgroup "IO"
191− [ benchIOSink value "foldrM" Ops.foldrMBuild
192− , benchIOSink value "foldl'" Ops.foldl'Build
193− , benchIOSink value "foldlM'" Ops.foldlM'Build
194− ]
195− , bgroup "Identity"
182+ [ bgroup "Identity"
196 [ benchIdentitySink value "foldrM" Ops.foldrMBuild
183 [ benchIdentitySink value "foldrM" Ops.foldrMBuild
197− , benchIdentitySink value "foldl'" Ops.foldl'Build
198− , benchIdentitySink value "foldlM'" Ops.foldlM'Build
199 ]
184 ]
200 ]
185 ]
201 , benchIOSink value "uncons" Ops.uncons
186 , benchIOSink value "uncons" Ops.uncons
@@ -203,8 +188,6 @@ main = do
203 , benchIOSink value "mapM_" Ops.mapM_
188 , benchIOSink value "mapM_" Ops.mapM_
204
189
205 , benchIOSink value "init" Ops.init
190 , benchIOSink value "init" Ops.init
206− , benchIOSink value "tail" Ops.tail
207− , benchIOSink value "nullHeadTail" Ops.nullHeadTail
208
191
209 -- this is too low and causes all benchmarks reported in ns
192 -- this is too low and causes all benchmarks reported in ns
210 -- , benchIOSink value "head" Ops.head
193 -- , benchIOSink value "head" Ops.head
@@ -233,8 +216,6 @@ main = do
233 , benchIOSink value "minimumBy" Ops.minimumBy
216 , benchIOSink value "minimumBy" Ops.minimumBy
234 , benchIOSink value "minimum" Ops.minimum
217 , benchIOSink value "minimum" Ops.minimum
235
218
236− , benchIOSink value "toList" Ops.toList
237− , benchIOSink value "toListRev" Ops.toListRev
238 ]
219 ]
239 , bgroup "folds"
220 , bgroup "folds"
240 [ benchIOSink value "drain" (S.fold FL.drain)
221 [ benchIOSink value "drain" (S.fold FL.drain)
@@ -245,7 +226,6 @@ main = do
245 , benchIOSink value "last" (S.fold FL.last)
226 , benchIOSink value "last" (S.fold FL.last)
246 , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
227 , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
247 , benchIOSink value "lastN.10" (S.fold (IA.lastN 10))
228 , benchIOSink value "lastN.10" (S.fold (IA.lastN 10))
248− , benchIOSink value "lastN.Max" (S.fold (IA.lastN (value + 1)))
249 , benchIOSink value "length" (S.fold FL.length)
229 , benchIOSink value "length" (S.fold FL.length)
250 , benchIOSink value "sum" (S.fold FL.sum)
230 , benchIOSink value "sum" (S.fold FL.sum)
251 , benchIOSink value "product" (S.fold FL.product)
231 , benchIOSink value "product" (S.fold FL.product)
@@ -260,12 +240,6 @@ main = do
260 , benchIOSink value "mconcat" (S.fold FL.mconcat . (S.map (Last . Just)))
240 , benchIOSink value "mconcat" (S.fold FL.mconcat . (S.map (Last . Just)))
261 , benchIOSink value "foldMap" (S.fold (FL.foldMap (Last . Just)))
241 , benchIOSink value "foldMap" (S.fold (FL.foldMap (Last . Just)))
262
242
263− , benchIOSink value "toList" (S.fold FL.toList)
264− , benchIOSink value "toListRevF" (S.fold IFL.toListRevF)
265− , benchIOSink value "toStream" (S.fold IP.toStream)
266− , benchIOSink value "toStreamRev" (S.fold IP.toStreamRev)
267− , benchIOSink value "writeN" (S.fold (A.writeN value))
268−
269 , benchIOSink value "index" (S.fold (FL.index (value + 1)))
243 , benchIOSink value "index" (S.fold (FL.index (value + 1)))
270 , benchIOSink value "head" (S.fold FL.head)
244 , benchIOSink value "head" (S.fold FL.head)
271 , benchIOSink value "find" (S.fold (FL.find (== (value + 1))))
245 , benchIOSink value "find" (S.fold (FL.find (== (value + 1))))
@@ -327,8 +301,6 @@ main = do
327 Ops.sequence serially (Ops.sourceUnfoldrMAction value n)
301 Ops.sequence serially (Ops.sourceUnfoldrMAction value n)
328 , benchIOSink value "findIndices" (Ops.findIndices value 1)
302 , benchIOSink value "findIndices" (Ops.findIndices value 1)
329 , benchIOSink value "elemIndices" (Ops.elemIndices value 1)
303 , benchIOSink value "elemIndices" (Ops.elemIndices value 1)
330− , benchIOSink value "reverse" (Ops.reverse 1)
331− , benchIOSink value "reverse'" (Ops.reverse' 1)
332 , benchIOSink value "foldrS" (Ops.foldrS 1)
304 , benchIOSink value "foldrS" (Ops.foldrS 1)
333 , benchIOSink value "foldrSMap" (Ops.foldrSMap 1)
305 , benchIOSink value "foldrSMap" (Ops.foldrSMap 1)
334 , benchIOSink value "foldrT" (Ops.foldrT 1)
306 , benchIOSink value "foldrT" (Ops.foldrT 1)
@@ -430,10 +402,6 @@ main = do
430 (Ops.concatMapWithWSerial 2 (value `div` 2))
402 (Ops.concatMapWithWSerial 2 (value `div` 2))
431 , benchIOSrc1 "concatMapWithWSerial (x/2,2)"
403 , benchIOSrc1 "concatMapWithWSerial (x/2,2)"
432 (Ops.concatMapWithWSerial (value `div` 2) 2)
404 (Ops.concatMapWithWSerial (value `div` 2) 2)
433− , benchIOSrc1 "concatUnfoldInterleaveRepl (x/4,4)"
434− (Ops.concatUnfoldInterleaveRepl4xN value)
435− , benchIOSrc1 "concatUnfoldRoundrobinRepl (x/4,4)"
436− (Ops.concatUnfoldRoundrobinRepl4xN value)
437 ]
405 ]
438 -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
406 -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
439 -- library. If scan/fold followed by a map is efficient enough we may not
407 -- library. If scan/fold followed by a map is efficient enough we may not
@@ -478,9 +446,63 @@ main = do
478 [ benchIOSink value "fmap" $ Ops.fmap' zipSerially 1
446 [ benchIOSink value "fmap" $ Ops.fmap' zipSerially 1
479 ]
447 ]
480 ]
448 ]
449+ -- Non-streaming operations. We keep these in a spearate group so that we
450+ -- can run these conveniently with smaller stream size.
451+ --
452+ -- These are also the operations that programmers should be aware of and
453+ -- should avoid using in a streaming application.
481− , bgroup "zipAsyncly"
454+ , bgroup "buffered"
482− [ bgroup "transformation"
455+ [ -- Inherently non-streaming operations
456+
457+ -- Right folds for reducing are inherently non-streaming as the
458+ -- expression needs to be fully built before it can be reduced.
459+ benchIOSink value "foldrM/reduce/IO" Ops.foldrMReduce
460+ , benchIdentitySink value "foldrM/reduce/Identity" Ops.foldrMReduce
461+
462+ -- Left folds for building a structure are inherently non-streaming as
463+ -- the structure cannot be lazily consumed until fully built.
483− [ benchIOSink value "fmap" $ Ops.fmap' zipAsyncly 1
464+ , benchIOSink value "foldl'/build/IO" Ops.foldl'Build
484− ]
465+ , benchIdentitySink value "foldl'/build/Identity" Ops.foldl'Build
466+ , benchIOSink value "foldlM'/build/IO" Ops.foldlM'Build
467+ , benchIdentitySink value "foldlM'/build/Identity" Ops.foldlM'Build
468+
469+ -- accumulation due to strictness of IO monad
470+ , benchIOSink value "foldrM/build/IO" Ops.foldrMBuild
471+ , benchPureSinkIO value "traversable/mapM" Ops.traversableMapM
472+
473+ -- Converting the stream to a list or pure stream
474+ , benchIOSink value "toList" Ops.toList
475+ , benchIOSink value "toListRev" Ops.toListRev
476+ , benchIOSink value "toStream" (S.fold IP.toStream)
477+ , benchIOSink value "toStreamRev" (S.fold IP.toStreamRev)
478+
479+ , benchIOSink value "folds/toList" (S.fold FL.toList)
480+ , benchIOSink value "folds/toListRevF" (S.fold IFL.toListRevF)
481+
482+ -- Converting the stream to an array
483+ , benchIOSink value "folds/lastN.Max" (S.fold (IA.lastN (value + 1)))
484+ , benchIOSink value "folds/writeN" (S.fold (A.writeN value))
485+
486+ -- Reversing/sorting a stream
487+ , benchIOSink value "reverse" (Ops.reverse 1)
488+ , benchIOSink value "reverse'" (Ops.reverse' 1)
489+
490+ -- XXX can these be streaming? Can we have special read/show style type
491+ -- classes supporting streaming?
492+ , mkString value `deepseq` (bench "readsPrec pure streams" $
493+ nf Ops.readInstance (mkString value))
494+ , mkString value `deepseq` (bench "readsPrec Haskell lists" $
495+ nf Ops.readInstanceList (mkListString value))
496+ , mkList value `deepseq` (bench "showPrec Haskell lists" $
497+ nf Ops.showInstanceList (mkList value))
498+
499+ -- XXX streaming operations that can potentially be fixed
500+ , benchPureSink value "foldable/sum" Ops.foldableSum
501+ , benchIOSink value "tail" Ops.tail
502+ , benchIOSink value "nullHeadTail" Ops.nullHeadTail
503+ , benchIOSrc1 "concatUnfoldInterleaveRepl (x/4,4)"
504+ (Ops.concatUnfoldInterleaveRepl4xN value)
505+ , benchIOSrc1 "concatUnfoldRoundrobinRepl (x/4,4)"
506+ (Ops.concatUnfoldRoundrobinRepl4xN value)
485− ]
507+ ]
486 ]
508 ]
benchmark/LinearAsync.hs+1
@@ -126,6 +126,7 @@ main = do
126 , benchIO value "zip" Ops.zipAsync
126 , benchIO value "zip" Ops.zipAsync
127 , benchIO value "zipM" Ops.zipAsyncM
127 , benchIO value "zipM" Ops.zipAsyncM
128 , benchIO value "zipAp" Ops.zipAsyncAp
128 , benchIO value "zipAp" Ops.zipAsyncAp
129+ , benchIO value "fmap zipAsyncly" $ Ops.fmap' zipAsyncly 1
129 -- Parallel stages in a pipeline
130 -- Parallel stages in a pipeline
130 , benchIO value "parAppMap" Ops.parAppMap
131 , benchIO value "parAppMap" Ops.parAppMap
131 , benchIO value "parAppSum" Ops.parAppSum
132 , benchIO value "parAppSum" Ops.parAppSum
benchmark/Nested.hs+4−4
@@ -34,8 +34,8 @@ main = do
34 [ benchIO "toNullAp" $ Ops.toNullAp linearCount serially
34 [ benchIO "toNullAp" $ Ops.toNullAp linearCount serially
35 , benchIO "toNull" $ Ops.toNull linearCount serially
35 , benchIO "toNull" $ Ops.toNull linearCount serially
36 , benchIO "toNull3" $ Ops.toNull3 linearCount serially
36 , benchIO "toNull3" $ Ops.toNull3 linearCount serially
37− , benchIO "toList" $ Ops.toList linearCount serially
37+ -- , benchIO "toList" $ Ops.toList linearCount serially
38− -- , benchIO "toListSome" $ Ops.toListSome serially
38+ , benchIO "toListSome" $ Ops.toListSome linearCount serially
39 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount serially
39 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount serially
40 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount serially
40 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount serially
41 , benchIO "filterSome" $ Ops.filterSome linearCount serially
41 , benchIO "filterSome" $ Ops.filterSome linearCount serially
@@ -46,8 +46,8 @@ main = do
46 [ benchIO "toNullAp" $ Ops.toNullAp linearCount wSerially
46 [ benchIO "toNullAp" $ Ops.toNullAp linearCount wSerially
47 , benchIO "toNull" $ Ops.toNull linearCount wSerially
47 , benchIO "toNull" $ Ops.toNull linearCount wSerially
48 , benchIO "toNull3" $ Ops.toNull3 linearCount wSerially
48 , benchIO "toNull3" $ Ops.toNull3 linearCount wSerially
49− , benchIO "toList" $ Ops.toList linearCount wSerially
49+ -- , benchIO "toList" $ Ops.toList linearCount wSerially
50− -- , benchIO "toListSome" $ Ops.toListSome wSerially
50+ , benchIO "toListSome" $ Ops.toListSome linearCount wSerially
51 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount wSerially
51 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount wSerially
52 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount wSerially
52 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount wSerially
53 , benchIO "filterSome" $ Ops.filterSome linearCount wSerially
53 , benchIO "filterSome" $ Ops.filterSome linearCount wSerially
benchmark/NestedConcurrent.hs+10−8
@@ -35,8 +35,8 @@ main = do
35 [ benchIO "toNullAp" $ Ops.toNullAp linearCount aheadly
35 [ benchIO "toNullAp" $ Ops.toNullAp linearCount aheadly
36 , benchIO "toNull" $ Ops.toNull linearCount aheadly
36 , benchIO "toNull" $ Ops.toNull linearCount aheadly
37 , benchIO "toNull3" $ Ops.toNull3 linearCount aheadly
37 , benchIO "toNull3" $ Ops.toNull3 linearCount aheadly
38− , benchIO "toList" $ Ops.toList linearCount aheadly
38+ -- , benchIO "toList" $ Ops.toList linearCount aheadly
39− -- , benchIO "toListSome" $ Ops.toListSome aheadly
39+ , benchIO "toListSome" $ Ops.toListSome linearCount aheadly
40 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount aheadly
40 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount aheadly
41 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount aheadly
41 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount aheadly
42 , benchIO "filterSome" $ Ops.filterSome linearCount aheadly
42 , benchIO "filterSome" $ Ops.filterSome linearCount aheadly
@@ -47,8 +47,8 @@ main = do
47 [ benchIO "toNullAp" $ Ops.toNullAp linearCount asyncly
47 [ benchIO "toNullAp" $ Ops.toNullAp linearCount asyncly
48 , benchIO "toNull" $ Ops.toNull linearCount asyncly
48 , benchIO "toNull" $ Ops.toNull linearCount asyncly
49 , benchIO "toNull3" $ Ops.toNull3 linearCount asyncly
49 , benchIO "toNull3" $ Ops.toNull3 linearCount asyncly
50− , benchIO "toList" $ Ops.toList linearCount asyncly
50+ -- , benchIO "toList" $ Ops.toList linearCount asyncly
51− -- , benchIO "toListSome" $ Ops.toListSome asyncly
51+ , benchIO "toListSome" $ Ops.toListSome linearCount asyncly
52 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount asyncly
52 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount asyncly
53 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount asyncly
53 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount asyncly
54 , benchIO "filterSome" $ Ops.filterSome linearCount asyncly
54 , benchIO "filterSome" $ Ops.filterSome linearCount asyncly
@@ -59,20 +59,22 @@ main = do
59 [ benchIO "toNullAp" $ Ops.toNullAp linearCount wAsyncly
59 [ benchIO "toNullAp" $ Ops.toNullAp linearCount wAsyncly
60 , benchIO "toNull" $ Ops.toNull linearCount wAsyncly
60 , benchIO "toNull" $ Ops.toNull linearCount wAsyncly
61 , benchIO "toNull3" $ Ops.toNull3 linearCount wAsyncly
61 , benchIO "toNull3" $ Ops.toNull3 linearCount wAsyncly
62− , benchIO "toList" $ Ops.toList linearCount wAsyncly
62+ -- , benchIO "toList" $ Ops.toList linearCount wAsyncly
63− -- , benchIO "toListSome" $ Ops.toListSome wAsyncly
63+ , benchIO "toListSome" $ Ops.toListSome linearCount wAsyncly
64 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount wAsyncly
64 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount wAsyncly
65 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount wAsyncly
65 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount wAsyncly
66 , benchIO "filterSome" $ Ops.filterSome linearCount wAsyncly
66 , benchIO "filterSome" $ Ops.filterSome linearCount wAsyncly
67 , benchIO "breakAfterSome" $ Ops.breakAfterSome linearCount wAsyncly
67 , benchIO "breakAfterSome" $ Ops.breakAfterSome linearCount wAsyncly
68 ]
68 ]
69
69
70+ -- XXX move this in a separate benchmark
70 , bgroup "parallely"
71 , bgroup "parallely"
71 [ benchIO "toNullAp" $ Ops.toNullAp linearCount parallely
72 [ benchIO "toNullAp" $ Ops.toNullAp linearCount parallely
72 , benchIO "toNull" $ Ops.toNull linearCount parallely
73 , benchIO "toNull" $ Ops.toNull linearCount parallely
73 , benchIO "toNull3" $ Ops.toNull3 linearCount parallely
74 , benchIO "toNull3" $ Ops.toNull3 linearCount parallely
74− , benchIO "toList" $ Ops.toList linearCount parallely
75+ -- , benchIO "toList" $ Ops.toList linearCount parallely
76+ -- XXX fix thread blocked indefinitely in MVar
75− --, benchIO "toListSome" $ Ops.toListSome parallely
77+ -- , benchIO "toListSome" $ Ops.toListSome linearCount parallely
76 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount parallely
78 , benchIO "filterAllOut" $ Ops.filterAllOut linearCount parallely
77 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount parallely
79 , benchIO "filterAllIn" $ Ops.filterAllIn linearCount parallely
78 , benchIO "filterSome" $ Ops.filterSome linearCount parallely
80 , benchIO "filterSome" $ Ops.filterSome linearCount parallely
benchmark/NestedOps.hs+3−1
@@ -101,12 +101,14 @@ toList linearCount t start = runToList . t $ do
101 where
101 where
102 nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
102 nestedCount2 = round (fromIntegral linearCount**(1/2::Double))
103
103
104+-- Taking a specified number of elements is very expensive in logict so we have
105+-- a test to measure the same.
104{-# INLINE toListSome #-}
106{-# INLINE toListSome #-}
105toListSome
107toListSome
106 :: (S.IsStream t, S.MonadAsync m, Monad (t m))
108 :: (S.IsStream t, S.MonadAsync m, Monad (t m))
107 => Int -> (t m Int -> S.SerialT m Int) -> Int -> m [Int]
109 => Int -> (t m Int -> S.SerialT m Int) -> Int -> m [Int]
108toListSome linearCount t start =
110toListSome linearCount t start =
109− runToList . t $ S.take 1000 $ do
111+ runToList . t $ S.take 10000 $ do
110 x <- source start nestedCount2
112 x <- source start nestedCount2
111 y <- source start nestedCount2
113 y <- source start nestedCount2
112 return $ x + y
114 return $ x + y