on master help sign in
Merge lib/B/Groups.hs into lib/B/Prelude.hs

* Remove lib/B/Group.hs * The idea: Have all the groups in Prelude and export only the groups, that way, all the functions aren't compiled multiple times (without and with inlining).

commit4d59cb3afef910cd668dbf175e1a4ee5b657a658 authoradithyaov <adithya@composewell.com> dateWed 26 Feb 2020, 16:54 (7 years ago) parent2dacf99
4 files changed+789−807
benchmark/Streamly/Benchmark/Prelude/Serial/O_1_Space.hs+1−1 benchmark/lib/Streamly/Benchmark/Groups.hs−792 benchmark/lib/Streamly/Benchmark/Prelude.hs+788−13 benchmark/streamly-benchmarks.cabal−1
benchmark/Streamly/Benchmark/Prelude/Serial/O_1_Space.hs+1−1
@@ -6,7 +6,7 @@
66-- Maintainer : streamly@composewell.com
77
88import Streamly.Benchmark.Common
9−import Streamly.Benchmark.Groups
9+import Streamly.Benchmark.Prelude
1010
1111import Gauge
1212
benchmark/lib/Streamly/Benchmark/Groups.hsdeleted−792
@@ -1,792 +0,0 @@
1−-- |
2−-- Module : Main
3−-- Copyright : (c) 2018 Harendra Kumar
4−--
5−-- License : BSD3
6−-- Maintainer : streamly@composewell.com
7−
8−module Streamly.Benchmark.Groups where
9−
10−import Control.DeepSeq (NFData(..))
11−import Data.Functor.Identity (Identity, runIdentity)
12−import Data.Monoid (Last(..))
13−import System.Random (randomRIO)
14−
15−import qualified GHC.Exts as GHC
16−import qualified Streamly.Benchmark.Prelude as Ops
17−
18−import Streamly
19−import qualified Streamly.Data.Fold as FL
20−import qualified Streamly.Prelude as S
21−import qualified Streamly.Internal.Data.Sink as Sink
22−
23−import Streamly.Internal.Data.Time.Units
24−import qualified Streamly.Internal.Memory.Array as IA
25−import qualified Streamly.Internal.Data.Fold as IFL
26−import qualified Streamly.Internal.Prelude as IP
27−import qualified Streamly.Internal.Data.Pipe as Pipe
28−
29−import qualified NestedOps as Nested
30−import qualified NestedUnfoldOps as NestedUnfold
31−
32−import Gauge
33−import Streamly.Benchmark.Common
34−
35−-------------------------------------------------------------------------------
36−--
37−-------------------------------------------------------------------------------
38−
39−-- We need a monadic bind here to make sure that the function f does not get
40−-- completely optimized out by the compiler in some cases.
41−
42−-- | Takes a fold method, and uses it with a default source.
43−{-# INLINE benchIOSink #-}
44−benchIOSink
45− :: (IsStream t, NFData b)
46− => Int -> String -> (t IO Int -> IO b) -> Benchmark
47−benchIOSink value name f = bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.source value
48−
49−{-# INLINE benchHoistSink #-}
50−benchHoistSink
51− :: (IsStream t, NFData b)
52− => Int -> String -> (t Identity Int -> IO b) -> Benchmark
53−benchHoistSink value name f =
54− bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.sourceUnfoldr value
55−
56−-- XXX We should be using sourceUnfoldrM for fair comparison with IO monad, but
57−-- we can't use it as it requires MonadAsync constraint.
58−{-# INLINE benchIdentitySink #-}
59−benchIdentitySink
60− :: (IsStream t, NFData b)
61− => Int -> String -> (t Identity Int -> Identity b) -> Benchmark
62−benchIdentitySink value name f = bench name $ nf (f . Ops.sourceUnfoldr value) 1
63−
64−-- | Takes a source, and uses it with a default drain/fold method.
65−{-# INLINE benchIOSrc #-}
66−benchIOSrc
67− :: (t IO a -> SerialT IO a)
68− -> String
69− -> (Int -> t IO a)
70− -> Benchmark
71−benchIOSrc t name f =
72− bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
73−
74−{-# INLINE benchPureSink #-}
75−benchPureSink :: NFData b => Int -> String -> (SerialT Identity Int -> b) -> Benchmark
76−benchPureSink value name f = benchPure name (Ops.sourceUnfoldr value) f
77−
78−benchIO :: (NFData b) => String -> (Int -> IO b) -> Benchmark
79−benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
80−
81−-------------------------------------------------------------------------------
82−-- Serial : O(1) Space
83−-------------------------------------------------------------------------------
84−
85−o_1_space_serial_pure :: Int -> [Benchmark]
86−o_1_space_serial_pure value =
87− [ bgroup
88− "serially"
89− [ bgroup
90− "pure"
91− [ benchPureSink value "id" id
92− , benchPureSink1 "eqBy" (Ops.eqByPure value)
93− , benchPureSink value "==" Ops.eqInstance
94− , benchPureSink value "/=" Ops.eqInstanceNotEq
95− , benchPureSink1 "cmpBy" (Ops.cmpByPure value)
96− , benchPureSink value "<" Ops.ordInstance
97− , benchPureSink value "min" Ops.ordInstanceMin
98− , benchPureSrc "IsList.fromList" (Ops.sourceIsList value)
99− -- length is used to check for foldr/build fusion
100− , benchPureSink
101− value
102− "length . IsList.toList"
103− (length . GHC.toList)
104− , benchPureSrc "IsString.fromString" (Ops.sourceIsString value)
105− , benchPureSink value "showsPrec pure streams" Ops.showInstance
106− , benchPureSink value "foldl'" Ops.pureFoldl'
107− ]
108− ]
109− ]
110−
111−o_1_space_serial_foldable :: Int -> [Benchmark]
112−o_1_space_serial_foldable value =
113− [ bgroup
114− "serially"
115− [ bgroup
116− "foldable"
117− -- Foldable instance
118− -- type class operations
119− [ bench "foldl'" $ nf (Ops.foldableFoldl' value) 1
120− , bench "foldrElem" $ nf (Ops.foldableFoldrElem value) 1
121− -- , bench "null" $ nf (Ops.foldableNull value) 1
122− , bench "elem" $ nf (Ops.foldableElem value) 1
123− , bench "length" $ nf (Ops.foldableLength value) 1
124− , bench "sum" $ nf (Ops.foldableSum value) 1
125− , bench "product" $ nf (Ops.foldableProduct value) 1
126− , bench "minimum" $ nf (Ops.foldableMin value) 1
127− , bench "maximum" $ nf (Ops.foldableMax value) 1
128− , bench "length . toList" $
129− nf (length . Ops.foldableToList value) 1
130− -- folds
131− , bench "notElem" $ nf (Ops.foldableNotElem value) 1
132− , bench "find" $ nf (Ops.foldableFind value) 1
133− , bench "all" $ nf (Ops.foldableAll value) 1
134− , bench "any" $ nf (Ops.foldableAny value) 1
135− , bench "and" $ nf (Ops.foldableAnd value) 1
136− , bench "or" $ nf (Ops.foldableOr value) 1
137− -- Note: minimumBy/maximumBy do not work in constant memory they are in
138− -- the O(n) group of benchmarks down below in this file.
139− -- Applicative and Traversable operations
140− -- TBD: traverse_
141− , benchIOSink1 "mapM_" (Ops.foldableMapM_ value)
142− -- TBD: for_
143− -- TBD: forM_
144− , benchIOSink1 "sequence_" (Ops.foldableSequence_ value)
145− -- TBD: sequenceA_
146− -- TBD: asum
147− -- , benchIOSink1 "msum" (Ops.foldableMsum value)
148− ]
149− ]
150− ]
151−
152−o_1_space_serial_generation :: Int -> [Benchmark]
153−o_1_space_serial_generation value =
154− [ bgroup
155− "serially"
156− [ bgroup
157− "generation"
158− -- Most basic, barely stream continuations running
159− [ benchIOSrc serially "unfoldr" (Ops.sourceUnfoldr value)
160− , benchIOSrc serially "unfoldrM" (Ops.sourceUnfoldrM value)
161− , benchIOSrc serially "intFromTo" (Ops.sourceIntFromTo value)
162− , benchIOSrc
163− serially
164− "intFromThenTo"
165− (Ops.sourceIntFromThenTo value)
166− , benchIOSrc
167− serially
168− "integerFromStep"
169− (Ops.sourceIntegerFromStep value)
170− , benchIOSrc
171− serially
172− "fracFromThenTo"
173− (Ops.sourceFracFromThenTo value)
174− , benchIOSrc serially "fracFromTo" (Ops.sourceFracFromTo value)
175− , benchIOSrc serially "fromList" (Ops.sourceFromList value)
176− , benchIOSrc serially "fromListM" (Ops.sourceFromListM value)
177− -- These are essentially cons and consM
178− , benchIOSrc
179− serially
180− "fromFoldable"
181− (Ops.sourceFromFoldable value)
182− , benchIOSrc
183− serially
184− "fromFoldableM"
185− (Ops.sourceFromFoldableM value)
186− , benchIOSrc serially "currentTime/0.00001s" $
187− Ops.currentTime value 0.00001
188− ]
189− ]
190− ]
191−
192−o_1_space_serial_elimination :: Int -> [Benchmark]
193−o_1_space_serial_elimination value =
194− [ bgroup
195− "serially"
196− [ bgroup
197− "elimination"
198− [ bgroup
199− "reduce"
200− [ bgroup
201− "IO"
202− [ benchIOSink value "foldl'" Ops.foldl'Reduce
203− , benchIOSink value "foldl1'" Ops.foldl1'Reduce
204− , benchIOSink value "foldlM'" Ops.foldlM'Reduce
205− ]
206− , bgroup
207− "Identity"
208− [ benchIdentitySink value "foldl'" Ops.foldl'Reduce
209− , benchIdentitySink
210− value
211− "foldl1'"
212− Ops.foldl1'Reduce
213− , benchIdentitySink
214− value
215− "foldlM'"
216− Ops.foldlM'Reduce
217− ]
218− ]
219− , bgroup
220− "build"
221− [ bgroup
222− "IO"
223− [ benchIOSink
224− value
225− "foldrMElem"
226− (Ops.foldrMElem value)
227− ]
228− , bgroup
229− "Identity"
230− [ benchIdentitySink
231− value
232− "foldrMElem"
233− (Ops.foldrMElem value)
234− , benchIdentitySink
235− value
236− "foldrMToStreamLength"
237− (S.length . runIdentity . Ops.foldrMToStream)
238− , benchPureSink
239− value
240− "foldrMToListLength"
241− (length . runIdentity . Ops.foldrMBuild)
242− ]
243− ]
244− , benchIOSink value "uncons" Ops.uncons
245− , benchIOSink value "toNull" $ Ops.toNull serially
246− , benchIOSink value "mapM_" Ops.mapM_
247− , benchIOSink value "init" Ops.init
248− -- this is too low and causes all benchmarks reported in ns
249− -- , benchIOSink value "head" Ops.head
250− , benchIOSink value "last" Ops.last
251− -- , benchIOSink value "lookup" Ops.lookup
252− , benchIOSink value "find" (Ops.find value)
253− , benchIOSink value "findIndex" (Ops.findIndex value)
254− , benchIOSink value "elemIndex" (Ops.elemIndex value)
255− -- this is too low and causes all benchmarks reported in ns
256− -- , benchIOSink value "null" Ops.null
257− , benchIOSink value "elem" (Ops.elem value)
258− , benchIOSink value "notElem" (Ops.notElem value)
259− , benchIOSink value "all" (Ops.all value)
260− , benchIOSink value "any" (Ops.any value)
261− , benchIOSink value "and" (Ops.and value)
262− , benchIOSink value "or" (Ops.or value)
263− , benchIOSink value "length" Ops.length
264− , benchHoistSink
265− value
266− "length . generally"
267− (Ops.length . IP.generally)
268− , benchIOSink value "sum" Ops.sum
269− , benchIOSink value "product" Ops.product
270− , benchIOSink value "maximumBy" Ops.maximumBy
271− , benchIOSink value "maximum" Ops.maximum
272− , benchIOSink value "minimumBy" Ops.minimumBy
273− , benchIOSink value "minimum" Ops.minimum
274− ]
275− ]
276− ]
277−
278−o_1_space_serial_folds :: Int -> [Benchmark]
279−o_1_space_serial_folds value =
280− [ bgroup
281− "serially"
282− [ bgroup
283− "folds"
284− [ benchIOSink value "drain" (S.fold FL.drain)
285− , benchIOSink value "drainN" (S.fold (IFL.drainN value))
286− , benchIOSink
287− value
288− "drainWhileTrue"
289− (S.fold (IFL.drainWhile $ (<=) (value + 1)))
290− , benchIOSink
291− value
292− "drainWhileFalse"
293− (S.fold (IFL.drainWhile $ (>=) (value + 1)))
294− , benchIOSink value "sink" (S.fold $ Sink.toFold Sink.drain)
295− , benchIOSink value "last" (S.fold FL.last)
296− , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
297− , benchIOSink value "lastN.10" (S.fold (IA.lastN 10))
298− , benchIOSink value "length" (S.fold FL.length)
299− , benchIOSink value "sum" (S.fold FL.sum)
300− , benchIOSink value "product" (S.fold FL.product)
301− , benchIOSink value "maximumBy" (S.fold (FL.maximumBy compare))
302− , benchIOSink value "maximum" (S.fold FL.maximum)
303− , benchIOSink value "minimumBy" (S.fold (FL.minimumBy compare))
304− , benchIOSink value "minimum" (S.fold FL.minimum)
305− , benchIOSink
306− value
307− "mean"
308− (\s ->
309− S.fold
310− FL.mean
311− (S.map (fromIntegral :: Int -> Double) s))
312− , benchIOSink
313− value
314− "variance"
315− (\s ->
316− S.fold
317− FL.variance
318− (S.map (fromIntegral :: Int -> Double) s))
319− , benchIOSink
320− value
321− "stdDev"
322− (\s ->
323− S.fold
324− FL.stdDev
325− (S.map (fromIntegral :: Int -> Double) s))
326− , benchIOSink
327− value
328− "mconcat"
329− (S.fold FL.mconcat . (S.map (Last . Just)))
330− , benchIOSink
331− value
332− "foldMap"
333− (S.fold (FL.foldMap (Last . Just)))
334− , benchIOSink value "index" (S.fold (FL.index (value + 1)))
335− , benchIOSink value "head" (S.fold FL.head)
336− , benchIOSink value "find" (S.fold (FL.find (== (value + 1))))
337− , benchIOSink
338− value
339− "findIndex"
340− (S.fold (FL.findIndex (== (value + 1))))
341− , benchIOSink
342− value
343− "elemIndex"
344− (S.fold (FL.elemIndex (value + 1)))
345− , benchIOSink value "null" (S.fold FL.null)
346− , benchIOSink value "elem" (S.fold (FL.elem (value + 1)))
347− , benchIOSink value "notElem" (S.fold (FL.notElem (value + 1)))
348− , benchIOSink value "all" (S.fold (FL.all (<= (value + 1))))
349− , benchIOSink value "any" (S.fold (FL.any (> (value + 1))))
350− , benchIOSink
351− value
352− "and"
353− (\s -> S.fold FL.and (S.map (<= (value + 1)) s))
354− , benchIOSink
355− value
356− "or"
357− (\s -> S.fold FL.or (S.map (> (value + 1)) s))
358− ]
359− ]
360− ]
361−
362−o_1_space_serial_foldMultiStream :: Int -> [Benchmark]
363−o_1_space_serial_foldMultiStream value =
364− [ bgroup
365− "serially"
366− [ bgroup
367− "fold-multi-stream"
368− [ benchIOSink1 "eqBy" (Ops.eqBy value)
369− , benchIOSink1 "cmpBy" (Ops.cmpBy value)
370− , benchIOSink value "isPrefixOf" Ops.isPrefixOf
371− , benchIOSink value "isSubsequenceOf" Ops.isSubsequenceOf
372− , benchIOSink value "stripPrefix" Ops.stripPrefix
373− ]
374− ]
375− ]
376−
377−o_1_space_serial_foldsTransforms :: Int -> [Benchmark]
378−o_1_space_serial_foldsTransforms value =
379− [ bgroup
380− "serially"
381− [ bgroup
382− "folds-transforms"
383− [ benchIOSink value "drain" (S.fold FL.drain)
384− , benchIOSink value "lmap" (S.fold (IFL.lmap (+ 1) FL.drain))
385− , benchIOSink
386− value
387− "pipe-mapM"
388− (S.fold
389− (IFL.transform
390− (Pipe.mapM (\x -> return $ x + 1))
391− FL.drain))
392− ]
393− ]
394− ]
395−
396−o_1_space_serial_foldsCompositions :: Int -> [Benchmark]
397−o_1_space_serial_foldsCompositions value =
398− [ bgroup
399− "serially"
400− [ bgroup
401− "folds-compositions" -- Applicative
402− [ benchIOSink
403− value
404− "all,any"
405− (S.fold
406− ((,) <$> FL.all (<= (value + 1)) <*>
407− FL.any (> (value + 1))))
408− , benchIOSink
409− value
410− "sum,length"
411− (S.fold ((,) <$> FL.sum <*> FL.length))
412− ]
413− ]
414− ]
415−
416−o_1_space_serial_pipes :: Int -> [Benchmark]
417−o_1_space_serial_pipes value =
418− [ bgroup
419− "serially"
420− [ bgroup
421− "pipes"
422− [ benchIOSink value "mapM" (Ops.transformMapM serially 1)
423− , benchIOSink
424− value
425− "compose"
426− (Ops.transformComposeMapM serially 1)
427− , benchIOSink value "tee" (Ops.transformTeeMapM serially 1)
428− , benchIOSink value "zip" (Ops.transformZipMapM serially 1)
429− ]
430− ]
431− ]
432−
433−o_1_space_serial_pipesX4 :: Int -> [Benchmark]
434−o_1_space_serial_pipesX4 value =
435− [ bgroup
436− "serially"
437− [ bgroup
438− "pipesX4"
439− [ benchIOSink value "mapM" (Ops.transformMapM serially 4)
440− , benchIOSink
441− value
442− "compose"
443− (Ops.transformComposeMapM serially 4)
444− , benchIOSink value "tee" (Ops.transformTeeMapM serially 4)
445− , benchIOSink value "zip" (Ops.transformZipMapM serially 4)
446− ]
447− ]
448− ]
449−
450−
451−o_1_space_serial_transformer :: Int -> [Benchmark]
452−o_1_space_serial_transformer value =
453− [ bgroup
454− "serially"
455− [ bgroup
456− "transformer"
457− [ benchIOSrc serially "evalState" (Ops.evalStateT value)
458− , benchIOSrc serially "withState" (Ops.withState value)
459− ]
460− ]
461− ]
462−
463−o_1_space_serial_transformation :: Int -> [Benchmark]
464−o_1_space_serial_transformation value =
465− [ bgroup
466− "serially"
467− [ bgroup
468− "transformation"
469− [ benchIOSink value "scanl" (Ops.scan 1)
470− , benchIOSink value "scanl1'" (Ops.scanl1' 1)
471− , benchIOSink value "map" (Ops.map 1)
472− , benchIOSink value "fmap" (Ops.fmap 1)
473− , benchIOSink value "mapM" (Ops.mapM serially 1)
474− , benchIOSink value "mapMaybe" (Ops.mapMaybe 1)
475− , benchIOSink value "mapMaybeM" (Ops.mapMaybeM 1)
476− , bench "sequence" $
477− nfIO $
478− randomRIO (1, 1000) >>= \n ->
479− Ops.sequence serially (Ops.sourceUnfoldrMAction value n)
480− , benchIOSink value "findIndices" (Ops.findIndices value 1)
481− , benchIOSink value "elemIndices" (Ops.elemIndices value 1)
482− , benchIOSink value "foldrS" (Ops.foldrS 1)
483− , benchIOSink value "foldrSMap" (Ops.foldrSMap 1)
484− , benchIOSink value "foldrT" (Ops.foldrT 1)
485− , benchIOSink value "foldrTMap" (Ops.foldrTMap 1)
486− , benchIOSink value "tap" (Ops.tap 1)
487− , benchIOSink value "tapRate 1 second" (Ops.tapRate 1)
488− , benchIOSink value "pollCounts 1 second" (Ops.pollCounts 1)
489− , benchIOSink value "tapAsync" (Ops.tapAsync 1)
490− , benchIOSink value "tapAsyncS" (Ops.tapAsyncS 1)
491− ]
492− ]
493− ]
494−
495−o_1_space_serial_transformationX4 :: Int -> [Benchmark]
496−o_1_space_serial_transformationX4 value =
497− [ bgroup
498− "serially"
499− [ bgroup
500− "transformationX4"
501− [ benchIOSink value "scan" (Ops.scan 4)
502− , benchIOSink value "scanl1'" (Ops.scanl1' 4)
503− , benchIOSink value "map" (Ops.map 4)
504− , benchIOSink value "fmap" (Ops.fmap 4)
505− , benchIOSink value "mapM" (Ops.mapM serially 4)
506− , benchIOSink value "mapMaybe" (Ops.mapMaybe 4)
507− , benchIOSink value "mapMaybeM" (Ops.mapMaybeM 4)
508− -- , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
509− -- Ops.sequence serially (Ops.sourceUnfoldrMAction n)
510− , benchIOSink value "findIndices" (Ops.findIndices value 4)
511− , benchIOSink value "elemIndices" (Ops.elemIndices value 4)
512− ]
513− ]
514− ]
515−
516−o_1_space_serial_filtering :: Int -> [Benchmark]
517−o_1_space_serial_filtering value =
518− [ bgroup
519− "serially"
520− [ bgroup
521− "filtering"
522− [ benchIOSink value "filter-even" (Ops.filterEven 1)
523− , benchIOSink value "filter-all-out" (Ops.filterAllOut value 1)
524− , benchIOSink value "filter-all-in" (Ops.filterAllIn value 1)
525− , benchIOSink value "take-all" (Ops.takeAll value 1)
526− , benchIOSink
527− value
528− "takeByTime-all"
529− (Ops.takeByTime (NanoSecond64 maxBound) 1)
530− , benchIOSink value "takeWhile-true" (Ops.takeWhileTrue value 1)
531− --, benchIOSink value "takeWhileM-true" (Ops.takeWhileMTrue 1)
532− -- "drop-one" is dual to "last"
533− , benchIOSink value "drop-one" (Ops.dropOne 1)
534− , benchIOSink value "drop-all" (Ops.dropAll value 1)
535− , benchIOSink
536− value
537− "dropByTime-all"
538− (Ops.dropByTime (NanoSecond64 maxBound) 1)
539− , benchIOSink value "dropWhile-true" (Ops.dropWhileTrue value 1)
540− --, benchIOSink value "dropWhileM-true" (Ops.dropWhileMTrue 1)
541− , benchIOSink
542− value
543− "dropWhile-false"
544− (Ops.dropWhileFalse value 1)
545− , benchIOSink value "deleteBy" (Ops.deleteBy value 1)
546− , benchIOSink value "intersperse" (Ops.intersperse value 1)
547− , benchIOSink value "insertBy" (Ops.insertBy value 1)
548− ]
549− ]
550− ]
551−
552−o_1_space_serial_filteringX4 :: Int -> [Benchmark]
553−o_1_space_serial_filteringX4 value =
554− [ bgroup
555− "serially"
556− [ bgroup
557− "filteringX4"
558− [ benchIOSink value "filter-even" (Ops.filterEven 4)
559− , benchIOSink value "filter-all-out" (Ops.filterAllOut value 4)
560− , benchIOSink value "filter-all-in" (Ops.filterAllIn value 4)
561− , benchIOSink value "take-all" (Ops.takeAll value 4)
562− , benchIOSink value "takeWhile-true" (Ops.takeWhileTrue value 4)
563− --, benchIOSink value "takeWhileM-true" (Ops.takeWhileMTrue 4)
564− , benchIOSink value "drop-one" (Ops.dropOne 4)
565− , benchIOSink value "drop-all" (Ops.dropAll value 4)
566− , benchIOSink value "dropWhile-true" (Ops.dropWhileTrue value 4)
567− --, benchIOSink value "dropWhileM-true" (Ops.dropWhileMTrue 4)
568− , benchIOSink
569− value
570− "dropWhile-false"
571− (Ops.dropWhileFalse value 4)
572− , benchIOSink value "deleteBy" (Ops.deleteBy value 4)
573− , benchIOSink value "intersperse" (Ops.intersperse value 4)
574− , benchIOSink value "insertBy" (Ops.insertBy value 4)
575− ]
576− ]
577− ]
578−
579−
580−o_1_space_serial_joining :: Int -> [Benchmark]
581−o_1_space_serial_joining value =
582− [ bgroup
583− "serially"
584− [ bgroup
585− "joining"
586− [ benchIOSrc1 "zip (2,x/2)" (Ops.zip (value `div` 2))
587− , benchIOSrc1 "zipM (2,x/2)" (Ops.zipM (value `div` 2))
588− , benchIOSrc1 "mergeBy (2,x/2)" (Ops.mergeBy (value `div` 2))
589− , benchIOSrc1 "serial (2,x/2)" (Ops.serial2 (value `div` 2))
590− , benchIOSrc1 "append (2,x/2)" (Ops.append2 (value `div` 2))
591− , benchIOSrc1 "serial (2,2,x/4)" (Ops.serial4 (value `div` 4))
592− , benchIOSrc1 "append (2,2,x/4)" (Ops.append4 (value `div` 4))
593− , benchIOSrc1 "wSerial (2,x/2)" (Ops.wSerial2 value) -- XXX Move this elsewhere?
594− , benchIOSrc1 "interleave (2,x/2)" (Ops.interleave2 value)
595− , benchIOSrc1 "roundRobin (2,x/2)" (Ops.roundRobin2 value)
596− ]
597− ]
598− ]
599−
600−
601−o_1_space_serial_concatFoldable :: Int -> [Benchmark]
602−o_1_space_serial_concatFoldable value =
603− [ bgroup
604− "serially"
605− [ bgroup
606− "concat-foldable"
607− [ benchIOSrc
608− serially
609− "foldMapWith"
610− (Ops.sourceFoldMapWith value)
611− , benchIOSrc
612− serially
613− "foldMapWithM"
614− (Ops.sourceFoldMapWithM value)
615− , benchIOSrc serially "foldMapM" (Ops.sourceFoldMapM value)
616− , benchIOSrc
617− serially
618− "foldWithConcatMapId"
619− (Ops.sourceConcatMapId value)
620− ]
621− ]
622− ]
623−
624−o_1_space_serial_concatSerial :: Int -> [Benchmark]
625−o_1_space_serial_concatSerial value =
626− [ bgroup
627− "serially"
628− [ bgroup
629− "concat-serial"
630− [ benchIOSrc1
631− "concatMapPure (2,x/2)"
632− (Ops.concatMapPure 2 (value `div` 2))
633− , benchIOSrc1
634− "concatMap (2,x/2)"
635− (Ops.concatMap 2 (value `div` 2))
636− , benchIOSrc1
637− "concatMap (x/2,2)"
638− (Ops.concatMap (value `div` 2) 2)
639− , benchIOSrc1
640− "concatMapRepl (x/4,4)"
641− (Ops.concatMapRepl4xN value)
642− , benchIOSrc1
643− "concatUnfoldRepl (x/4,4)"
644− (Ops.concatUnfoldRepl4xN value)
645− , benchIOSrc1
646− "concatMapWithSerial (2,x/2)"
647− (Ops.concatMapWithSerial 2 (value `div` 2))
648− , benchIOSrc1
649− "concatMapWithSerial (x/2,2)"
650− (Ops.concatMapWithSerial (value `div` 2) 2)
651− , benchIOSrc1
652− "concatMapWithAppend (2,x/2)"
653− (Ops.concatMapWithAppend 2 (value `div` 2))
654− ]
655− ]
656− ]
657−
658−
659−o_1_space_serial_outerProductStreams :: Int -> [Benchmark]
660−o_1_space_serial_outerProductStreams value =
661− [ bgroup
662− "serially"
663− [ bgroup
664− "outer-product-streams"
665− [ benchIO "toNullAp" $ Nested.toNullAp value serially
666− , benchIO "toNull" $ Nested.toNull value serially
667− , benchIO "toNull3" $ Nested.toNull3 value serially
668− , benchIO "filterAllOut" $ Nested.filterAllOut value serially
669− , benchIO "filterAllIn" $ Nested.filterAllIn value serially
670− , benchIO "filterSome" $ Nested.filterSome value serially
671− , benchIO "breakAfterSome" $
672− Nested.breakAfterSome value serially
673− ]
674− ]
675− ]
676−
677−
678−o_1_space_serial_outerProductUnfolds :: Int -> [Benchmark]
679−o_1_space_serial_outerProductUnfolds value =
680− [ bgroup
681− "serially"
682− [ bgroup
683− "outer-product-unfolds"
684− [ benchIO "toNull" $ NestedUnfold.toNull value
685− , benchIO "toNull3" $ NestedUnfold.toNull3 value
686− , benchIO "concat" $ NestedUnfold.concat value
687− , benchIO "filterAllOut" $ NestedUnfold.filterAllOut value
688− , benchIO "filterAllIn" $ NestedUnfold.filterAllIn value
689− , benchIO "filterSome" $ NestedUnfold.filterSome value
690− , benchIO "breakAfterSome" $ NestedUnfold.breakAfterSome value
691− ]
692− ]
693− ]
694−
695−
696−o_1_space_serial_mixed :: Int -> [Benchmark]
697−o_1_space_serial_mixed value =
698− [ bgroup
699− "serially"
700− -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
701− -- library. If scan/fold followed by a map is efficient enough we may not
702− -- need monolithic implementations of these.
703− [ bgroup
704− "mixed"
705− [ benchIOSink value "scanl-map" (Ops.scanMap 1)
706− , benchIOSink value "foldl-map" Ops.foldl'ReduceMap
707− , benchIOSink value "sum-product-fold" Ops.sumProductFold
708− , benchIOSink value "sum-product-scan" Ops.sumProductScan
709− ]
710− ]
711− ]
712−
713−o_1_space_serial_mixedX4 :: Int -> [Benchmark]
714−o_1_space_serial_mixedX4 value =
715− [ bgroup
716− "serially"
717− [ bgroup
718− "mixedX4"
719− [ benchIOSink value "scan-map" (Ops.scanMap 4)
720− , benchIOSink value "drop-map" (Ops.dropMap 4)
721− , benchIOSink value "drop-scan" (Ops.dropScan 4)
722− , benchIOSink value "take-drop" (Ops.takeDrop value 4)
723− , benchIOSink value "take-scan" (Ops.takeScan value 4)
724− , benchIOSink value "take-map" (Ops.takeMap value 4)
725− , benchIOSink value "filter-drop" (Ops.filterDrop value 4)
726− , benchIOSink value "filter-take" (Ops.filterTake value 4)
727− , benchIOSink value "filter-scan" (Ops.filterScan 4)
728− , benchIOSink value "filter-scanl1" (Ops.filterScanl1 4)
729− , benchIOSink value "filter-map" (Ops.filterMap value 4)
730− ]
731− ]
732− ]
733−
734−o_1_space_wSerial_transformation :: Int -> [Benchmark]
735−o_1_space_wSerial_transformation value =
736− [ bgroup
737− "wSerially"
738− [ bgroup
739− "transformation"
740− [benchIOSink value "fmap" $ Ops.fmap' wSerially 1]
741− ]
742− ]
743−
744−o_1_space_wSerial_concatMap :: Int -> [Benchmark]
745−o_1_space_wSerial_concatMap value =
746− [ bgroup
747− "wSerially"
748− [ bgroup
749− "concatMap"
750− [ benchIOSrc1
751− "concatMapWithWSerial (2,x/2)"
752− (Ops.concatMapWithWSerial 2 (value `div` 2))
753− , benchIOSrc1
754− "concatMapWithWSerial (x/2,2)"
755− (Ops.concatMapWithWSerial (value `div` 2) 2)
756− ]
757− ]
758− ]
759−
760−o_1_space_wSerial_outerProduct :: Int -> [Benchmark]
761−o_1_space_wSerial_outerProduct value =
762− [ bgroup
763− "wSerially"
764− [ bgroup
765− "outer-product"
766− [ benchIO "toNullAp" $ Nested.toNullAp value wSerially
767− , benchIO "toNull" $ Nested.toNull value wSerially
768− , benchIO "toNull3" $ Nested.toNull3 value wSerially
769− , benchIO "filterAllOut" $ Nested.filterAllOut value wSerially
770− , benchIO "filterAllIn" $ Nested.filterAllIn value wSerially
771− , benchIO "filterSome" $ Nested.filterSome value wSerially
772− , benchIO "breakAfterSome" $
773− Nested.breakAfterSome value wSerially
774− ]
775− ]
776− ]
777−
778−o_1_space_zipSerial_transformation :: Int -> [Benchmark]
779−o_1_space_zipSerial_transformation value =
780− [ bgroup
781− "zipSerially"
782− [ bgroup
783− "transformation"
784− [benchIOSink value "fmap" $ Ops.fmap' zipSerially 1]
785− -- XXX needs fixing
786− {-
787− , bgroup "outer-product"
788− [ benchIO "toNullAp" $ Nested.toNullAp value zipSerially
789− ]
790− -}
791− ]
792− ]
benchmark/lib/Streamly/Benchmark/Prelude.hs+788−13
@@ -23,16 +23,18 @@
2323
2424module Streamly.Benchmark.Prelude where
2525
26−import Control.DeepSeq (NFData)
26+import Control.DeepSeq (NFData(..))
2727import Control.Monad (when)
2828import Control.Monad.IO.Class (MonadIO(..))
2929import Control.Monad.State.Strict (StateT, get, put)
3030import Data.Functor.Identity (Identity, runIdentity)
3131import Data.IORef (newIORef, modifyIORef')
32+import Data.Monoid (Last(..))
3233import GHC.Generics (Generic)
34+import System.Random (randomRIO)
3335import Prelude
34− (Monad, Int, (+), ($), (.), return, fmap, even, (>), (<=), (==), (>=),
35− subtract, undefined, Maybe(..), odd, Bool, not, (>>=), mapM_, curry,
36+ (Monad, String, Int, (+), ($), (.), return, even, (>), (<=), (==), (>=),
37+ subtract, undefined, Maybe(..), Bool, not, (>>=), curry,
3638 maxBound, div, IO, compare, Double, fromIntegral, Integer, (<$>),
3739 (<*>), flip)
3840import qualified Prelude as P
@@ -46,6 +48,7 @@ import Test.Inspection
4648import qualified Streamly.Internal.Data.Stream.StreamD as D
4749#endif
4850
51+import Streamly (SerialT, IsStream, wSerially, zipSerially, serially)
4952import qualified Streamly as S hiding (runStream)
5053import qualified Streamly.Prelude as S
5154import qualified Streamly.Internal.Prelude as Internal
@@ -55,6 +58,19 @@ import qualified Streamly.Internal.Data.Pipe as Pipe
5558import qualified Streamly.Internal.Data.Stream.Parallel as Par
5659import Streamly.Internal.Data.Time.Units
5760
61+import qualified Streamly.Internal.Data.Sink as Sink
62+
63+import qualified Streamly.Internal.Memory.Array as IA
64+import qualified Streamly.Internal.Data.Fold as IFL
65+import qualified Streamly.Internal.Prelude as IP
66+
67+import qualified NestedOps as Nested
68+import qualified NestedUnfoldOps as NestedUnfold
69+
70+import Gauge
71+import Streamly.Benchmark.Common
72+
73+
5874type Stream m a = S.SerialT m a
5975
6076-------------------------------------------------------------------------------
@@ -155,7 +171,7 @@ sourceFromIndices value n = S.take value $ S.fromIndices (+ n)
155171
156172{-# INLINE sourceFromIndicesM #-}
157173sourceFromIndicesM :: (S.MonadAsync m, S.IsStream t) => Int -> Int -> t m Int
158−sourceFromIndicesM value n = S.take value $ S.fromIndicesM (Prelude.fmap return (+ n))
174+sourceFromIndicesM value n = S.take value $ S.fromIndicesM (P.fmap return (+ n))
159175
160176-- fromList
161177
@@ -165,7 +181,7 @@ sourceFromList value n = S.fromList [n..n+value]
165181
166182{-# INLINE sourceFromListM #-}
167183sourceFromListM :: (S.MonadAsync m, S.IsStream t) => Int -> Int -> t m Int
168−sourceFromListM value n = S.fromListM (Prelude.fmap return [n..n+value])
184+sourceFromListM value n = S.fromListM (P.fmap return [n..n+value])
169185
170186{-# INLINE sourceIsList #-}
171187sourceIsList :: Int -> Int -> S.SerialT Identity Int
@@ -183,7 +199,7 @@ sourceFromFoldable value n = S.fromFoldable [n..n+value]
183199
184200{-# INLINE sourceFromFoldableM #-}
185201sourceFromFoldableM :: (S.IsStream t, S.MonadAsync m) => Int -> Int -> t m Int
186−sourceFromFoldableM value n = S.fromFoldableM (Prelude.fmap return [n..n+value])
202+sourceFromFoldableM value n = S.fromFoldableM (P.fmap return [n..n+value])
187203
188204{-# INLINE currentTime #-}
189205currentTime :: (S.IsStream t, S.MonadAsync m)
@@ -262,11 +278,11 @@ uncons s = do
262278
263279{-# INLINE init #-}
264280init :: Monad m => Stream m a -> m ()
265−init s = S.init s >>= Prelude.mapM_ S.drain
281+init s = S.init s >>= P.mapM_ S.drain
266282
267283{-# INLINE tail #-}
268284tail :: Monad m => Stream m a -> m ()
269−tail s = S.tail s >>= Prelude.mapM_ tail
285+tail s = S.tail s >>= P.mapM_ tail
270286
271287{-# INLINE nullHeadTail #-}
272288nullHeadTail :: Monad m => Stream m Int -> m ()
@@ -274,7 +290,7 @@ nullHeadTail s = do
274290 r <- S.null s
275291 when (not r) $ do
276292 _ <- S.head s
277− S.tail s >>= Prelude.mapM_ nullHeadTail
293+ S.tail s >>= P.mapM_ nullHeadTail
278294
279295{-# INLINE mapM_ #-}
280296mapM_ :: Monad m => Stream m Int -> m ()
@@ -419,8 +435,8 @@ sequence :: (S.IsStream t, S.MonadAsync m)
419435
420436scan n = composeN n $ S.scanl' (+) 0
421437scanl1' n = composeN n $ S.scanl1' (+)
422−fmap n = composeN n $ Prelude.fmap (+1)
423−fmap' t n = composeN' n $ t . Prelude.fmap (+1)
438+fmap n = composeN n $ P.fmap (+1)
439+fmap' t n = composeN' n $ t . P.fmap (+1)
424440map n = composeN n $ S.map (+1)
425441map' t n = composeN' n $ t . S.map (+1)
426442mapM t n = composeN' n $ t . S.mapM return
@@ -450,9 +466,9 @@ tapAsync :: S.MonadAsync m => Int -> Stream m Int -> m ()
450466tapAsync n = composeN n $ Internal.tapAsync FL.sum
451467
452468mapMaybe n = composeN n $ S.mapMaybe
453− (\x -> if Prelude.odd x then Nothing else Just x)
469+ (\x -> if P.odd x then Nothing else Just x)
454470mapMaybeM n = composeN n $ S.mapMaybeM
455− (\x -> if Prelude.odd x then return Nothing else return $ Just x)
471+ (\x -> if P.odd x then return Nothing else return $ Just x)
456472sequence t = transform . t . S.sequence
457473filterEven n = composeN n $ S.filter even
458474filterAllOut value n = composeN n $ S.filter (> (value + 1))
@@ -1221,3 +1237,762 @@ traversableMapM = P.mapM return
12211237{-# INLINE traversableSequence #-}
12221238traversableSequence :: Stream Identity Int -> IO (Stream Identity Int)
12231239traversableSequence = P.sequence . P.fmap return
1240+
1241+-------------------------------------------------------------------------------
1242+-- Benchmark groups
1243+-------------------------------------------------------------------------------
1244+
1245+-- We need a monadic bind here to make sure that the function f does not get
1246+-- completely optimized out by the compiler in some cases.
1247+
1248+-- | Takes a fold method, and uses it with a default source.
1249+{-# INLINE benchIOSink #-}
1250+benchIOSink
1251+ :: (IsStream t, NFData b)
1252+ => Int -> String -> (t IO Int -> IO b) -> Benchmark
1253+benchIOSink value name f = bench name $ nfIO $ randomRIO (1,1) >>= f . source value
1254+
1255+{-# INLINE benchHoistSink #-}
1256+benchHoistSink
1257+ :: (IsStream t, NFData b)
1258+ => Int -> String -> (t Identity Int -> IO b) -> Benchmark
1259+benchHoistSink value name f =
1260+ bench name $ nfIO $ randomRIO (1,1) >>= f . sourceUnfoldr value
1261+
1262+-- XXX We should be using sourceUnfoldrM for fair comparison with IO monad, but
1263+-- we can't use it as it requires MonadAsync constraint.
1264+{-# INLINE benchIdentitySink #-}
1265+benchIdentitySink
1266+ :: (IsStream t, NFData b)
1267+ => Int -> String -> (t Identity Int -> Identity b) -> Benchmark
1268+benchIdentitySink value name f = bench name $ nf (f . sourceUnfoldr value) 1
1269+
1270+-- | Takes a source, and uses it with a default drain/fold method.
1271+{-# INLINE benchIOSrc #-}
1272+benchIOSrc
1273+ :: (t IO a -> SerialT IO a)
1274+ -> String
1275+ -> (Int -> t IO a)
1276+ -> Benchmark
1277+benchIOSrc t name f =
1278+ bench name $ nfIO $ randomRIO (1,1) >>= toNull t . f
1279+
1280+{-# INLINE benchPureSink #-}
1281+benchPureSink :: NFData b => Int -> String -> (SerialT Identity Int -> b) -> Benchmark
1282+benchPureSink value name f = benchPure name (sourceUnfoldr value) f
1283+
1284+benchIO :: (NFData b) => String -> (Int -> IO b) -> Benchmark
1285+benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
1286+
1287+-------------------------------------------------------------------------------
1288+-- Serial : O(1) Space
1289+-------------------------------------------------------------------------------
1290+
1291+o_1_space_serial_pure :: Int -> [Benchmark]
1292+o_1_space_serial_pure value =
1293+ [ bgroup
1294+ "serially"
1295+ [ bgroup
1296+ "pure"
1297+ [ benchPureSink value "id" P.id
1298+ , benchPureSink1 "eqBy" (eqByPure value)
1299+ , benchPureSink value "==" eqInstance
1300+ , benchPureSink value "/=" eqInstanceNotEq
1301+ , benchPureSink1 "cmpBy" (cmpByPure value)
1302+ , benchPureSink value "<" ordInstance
1303+ , benchPureSink value "min" ordInstanceMin
1304+ , benchPureSrc "IsList.fromList" (sourceIsList value)
1305+ -- length is used to check for foldr/build fusion
1306+ , benchPureSink
1307+ value
1308+ "length . IsList.toList"
1309+ (P.length . GHC.toList)
1310+ , benchPureSrc "IsString.fromString" (sourceIsString value)
1311+ , benchPureSink value "showsPrec pure streams" showInstance
1312+ , benchPureSink value "foldl'" pureFoldl'
1313+ ]
1314+ ]
1315+ ]
1316+
1317+o_1_space_serial_foldable :: Int -> [Benchmark]
1318+o_1_space_serial_foldable value =
1319+ [ bgroup
1320+ "serially"
1321+ [ bgroup
1322+ "foldable"
1323+ -- Foldable instance
1324+ -- type class operations
1325+ [ bench "foldl'" $ nf (foldableFoldl' value) 1
1326+ , bench "foldrElem" $ nf (foldableFoldrElem value) 1
1327+ -- , bench "null" $ nf (foldableNull value) 1
1328+ , bench "elem" $ nf (foldableElem value) 1
1329+ , bench "length" $ nf (foldableLength value) 1
1330+ , bench "sum" $ nf (foldableSum value) 1
1331+ , bench "product" $ nf (foldableProduct value) 1
1332+ , bench "minimum" $ nf (foldableMin value) 1
1333+ , bench "maximum" $ nf (foldableMax value) 1
1334+ , bench "length . toList" $
1335+ nf (P.length . foldableToList value) 1
1336+ -- folds
1337+ , bench "notElem" $ nf (foldableNotElem value) 1
1338+ , bench "find" $ nf (foldableFind value) 1
1339+ , bench "all" $ nf (foldableAll value) 1
1340+ , bench "any" $ nf (foldableAny value) 1
1341+ , bench "and" $ nf (foldableAnd value) 1
1342+ , bench "or" $ nf (foldableOr value) 1
1343+ -- Note: minimumBy/maximumBy do not work in constant memory they are in
1344+ -- the O(n) group of benchmarks down below in this file.
1345+ -- Applicative and Traversable operations
1346+ -- TBD: traverse_
1347+ , benchIOSink1 "mapM_" (foldableMapM_ value)
1348+ -- TBD: for_
1349+ -- TBD: forM_
1350+ , benchIOSink1 "sequence_" (foldableSequence_ value)
1351+ -- TBD: sequenceA_
1352+ -- TBD: asum
1353+ -- , benchIOSink1 "msum" (foldableMsum value)
1354+ ]
1355+ ]
1356+ ]
1357+
1358+o_1_space_serial_generation :: Int -> [Benchmark]
1359+o_1_space_serial_generation value =
1360+ [ bgroup
1361+ "serially"
1362+ [ bgroup
1363+ "generation"
1364+ -- Most basic, barely stream continuations running
1365+ [ benchIOSrc serially "unfoldr" (sourceUnfoldr value)
1366+ , benchIOSrc serially "unfoldrM" (sourceUnfoldrM value)
1367+ , benchIOSrc serially "intFromTo" (sourceIntFromTo value)
1368+ , benchIOSrc
1369+ serially
1370+ "intFromThenTo"
1371+ (sourceIntFromThenTo value)
1372+ , benchIOSrc
1373+ serially
1374+ "integerFromStep"
1375+ (sourceIntegerFromStep value)
1376+ , benchIOSrc
1377+ serially
1378+ "fracFromThenTo"
1379+ (sourceFracFromThenTo value)
1380+ , benchIOSrc serially "fracFromTo" (sourceFracFromTo value)
1381+ , benchIOSrc serially "fromList" (sourceFromList value)
1382+ , benchIOSrc serially "fromListM" (sourceFromListM value)
1383+ -- These are essentially cons and consM
1384+ , benchIOSrc
1385+ serially
1386+ "fromFoldable"
1387+ (sourceFromFoldable value)
1388+ , benchIOSrc
1389+ serially
1390+ "fromFoldableM"
1391+ (sourceFromFoldableM value)
1392+ , benchIOSrc serially "currentTime/0.00001s" $
1393+ currentTime value 0.00001
1394+ ]
1395+ ]
1396+ ]
1397+
1398+o_1_space_serial_elimination :: Int -> [Benchmark]
1399+o_1_space_serial_elimination value =
1400+ [ bgroup
1401+ "serially"
1402+ [ bgroup
1403+ "elimination"
1404+ [ bgroup
1405+ "reduce"
1406+ [ bgroup
1407+ "IO"
1408+ [ benchIOSink value "foldl'" foldl'Reduce
1409+ , benchIOSink value "foldl1'" foldl1'Reduce
1410+ , benchIOSink value "foldlM'" foldlM'Reduce
1411+ ]
1412+ , bgroup
1413+ "Identity"
1414+ [ benchIdentitySink value "foldl'" foldl'Reduce
1415+ , benchIdentitySink
1416+ value
1417+ "foldl1'"
1418+ foldl1'Reduce
1419+ , benchIdentitySink
1420+ value
1421+ "foldlM'"
1422+ foldlM'Reduce
1423+ ]
1424+ ]
1425+ , bgroup
1426+ "build"
1427+ [ bgroup
1428+ "IO"
1429+ [ benchIOSink
1430+ value
1431+ "foldrMElem"
1432+ (foldrMElem value)
1433+ ]
1434+ , bgroup
1435+ "Identity"
1436+ [ benchIdentitySink
1437+ value
1438+ "foldrMElem"
1439+ (foldrMElem value)
1440+ , benchIdentitySink
1441+ value
1442+ "foldrMToStreamLength"
1443+ (S.length . runIdentity . foldrMToStream)
1444+ , benchPureSink
1445+ value
1446+ "foldrMToListLength"
1447+ (P.length . runIdentity . foldrMBuild)
1448+ ]
1449+ ]
1450+ , benchIOSink value "uncons" uncons
1451+ , benchIOSink value "toNull" $ toNull serially
1452+ , benchIOSink value "mapM_" mapM_
1453+ , benchIOSink value "init" init
1454+ -- this is too low and causes all benchmarks reported in ns
1455+ -- , benchIOSink value "head" head
1456+ , benchIOSink value "last" last
1457+ -- , benchIOSink value "lookup" lookup
1458+ , benchIOSink value "find" (find value)
1459+ , benchIOSink value "findIndex" (findIndex value)
1460+ , benchIOSink value "elemIndex" (elemIndex value)
1461+ -- this is too low and causes all benchmarks reported in ns
1462+ -- , benchIOSink value "null" null
1463+ , benchIOSink value "elem" (elem value)
1464+ , benchIOSink value "notElem" (notElem value)
1465+ , benchIOSink value "all" (all value)
1466+ , benchIOSink value "any" (any value)
1467+ , benchIOSink value "and" (and value)
1468+ , benchIOSink value "or" (or value)
1469+ , benchIOSink value "length" length
1470+ , benchHoistSink
1471+ value
1472+ "length . generally"
1473+ (length . IP.generally)
1474+ , benchIOSink value "sum" sum
1475+ , benchIOSink value "product" product
1476+ , benchIOSink value "maximumBy" maximumBy
1477+ , benchIOSink value "maximum" maximum
1478+ , benchIOSink value "minimumBy" minimumBy
1479+ , benchIOSink value "minimum" minimum
1480+ ]
1481+ ]
1482+ ]
1483+
1484+o_1_space_serial_folds :: Int -> [Benchmark]
1485+o_1_space_serial_folds value =
1486+ [ bgroup
1487+ "serially"
1488+ [ bgroup
1489+ "folds"
1490+ [ benchIOSink value "drain" (S.fold FL.drain)
1491+ , benchIOSink value "drainN" (S.fold (IFL.drainN value))
1492+ , benchIOSink
1493+ value
1494+ "drainWhileTrue"
1495+ (S.fold (IFL.drainWhile $ (<=) (value + 1)))
1496+ , benchIOSink
1497+ value
1498+ "drainWhileFalse"
1499+ (S.fold (IFL.drainWhile $ (>=) (value + 1)))
1500+ , benchIOSink value "sink" (S.fold $ Sink.toFold Sink.drain)
1501+ , benchIOSink value "last" (S.fold FL.last)
1502+ , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
1503+ , benchIOSink value "lastN.10" (S.fold (IA.lastN 10))
1504+ , benchIOSink value "length" (S.fold FL.length)
1505+ , benchIOSink value "sum" (S.fold FL.sum)
1506+ , benchIOSink value "product" (S.fold FL.product)
1507+ , benchIOSink value "maximumBy" (S.fold (FL.maximumBy compare))
1508+ , benchIOSink value "maximum" (S.fold FL.maximum)
1509+ , benchIOSink value "minimumBy" (S.fold (FL.minimumBy compare))
1510+ , benchIOSink value "minimum" (S.fold FL.minimum)
1511+ , benchIOSink
1512+ value
1513+ "mean"
1514+ (\s ->
1515+ S.fold
1516+ FL.mean
1517+ (S.map (fromIntegral :: Int -> Double) s))
1518+ , benchIOSink
1519+ value
1520+ "variance"
1521+ (\s ->
1522+ S.fold
1523+ FL.variance
1524+ (S.map (fromIntegral :: Int -> Double) s))
1525+ , benchIOSink
1526+ value
1527+ "stdDev"
1528+ (\s ->
1529+ S.fold
1530+ FL.stdDev
1531+ (S.map (fromIntegral :: Int -> Double) s))
1532+ , benchIOSink
1533+ value
1534+ "mconcat"
1535+ (S.fold FL.mconcat . (S.map (Last . Just)))
1536+ , benchIOSink
1537+ value
1538+ "foldMap"
1539+ (S.fold (FL.foldMap (Last . Just)))
1540+ , benchIOSink value "index" (S.fold (FL.index (value + 1)))
1541+ , benchIOSink value "head" (S.fold FL.head)
1542+ , benchIOSink value "find" (S.fold (FL.find (== (value + 1))))
1543+ , benchIOSink
1544+ value
1545+ "findIndex"
1546+ (S.fold (FL.findIndex (== (value + 1))))
1547+ , benchIOSink
1548+ value
1549+ "elemIndex"
1550+ (S.fold (FL.elemIndex (value + 1)))
1551+ , benchIOSink value "null" (S.fold FL.null)
1552+ , benchIOSink value "elem" (S.fold (FL.elem (value + 1)))
1553+ , benchIOSink value "notElem" (S.fold (FL.notElem (value + 1)))
1554+ , benchIOSink value "all" (S.fold (FL.all (<= (value + 1))))
1555+ , benchIOSink value "any" (S.fold (FL.any (> (value + 1))))
1556+ , benchIOSink
1557+ value
1558+ "and"
1559+ (\s -> S.fold FL.and (S.map (<= (value + 1)) s))
1560+ , benchIOSink
1561+ value
1562+ "or"
1563+ (\s -> S.fold FL.or (S.map (> (value + 1)) s))
1564+ ]
1565+ ]
1566+ ]
1567+
1568+o_1_space_serial_foldMultiStream :: Int -> [Benchmark]
1569+o_1_space_serial_foldMultiStream value =
1570+ [ bgroup
1571+ "serially"
1572+ [ bgroup
1573+ "fold-multi-stream"
1574+ [ benchIOSink1 "eqBy" (eqBy value)
1575+ , benchIOSink1 "cmpBy" (cmpBy value)
1576+ , benchIOSink value "isPrefixOf" isPrefixOf
1577+ , benchIOSink value "isSubsequenceOf" isSubsequenceOf
1578+ , benchIOSink value "stripPrefix" stripPrefix
1579+ ]
1580+ ]
1581+ ]
1582+
1583+o_1_space_serial_foldsTransforms :: Int -> [Benchmark]
1584+o_1_space_serial_foldsTransforms value =
1585+ [ bgroup
1586+ "serially"
1587+ [ bgroup
1588+ "folds-transforms"
1589+ [ benchIOSink value "drain" (S.fold FL.drain)
1590+ , benchIOSink value "lmap" (S.fold (IFL.lmap (+ 1) FL.drain))
1591+ , benchIOSink
1592+ value
1593+ "pipe-mapM"
1594+ (S.fold
1595+ (IFL.transform
1596+ (Pipe.mapM (\x -> return $ x + 1))
1597+ FL.drain))
1598+ ]
1599+ ]
1600+ ]
1601+
1602+o_1_space_serial_foldsCompositions :: Int -> [Benchmark]
1603+o_1_space_serial_foldsCompositions value =
1604+ [ bgroup
1605+ "serially"
1606+ [ bgroup
1607+ "folds-compositions" -- Applicative
1608+ [ benchIOSink
1609+ value
1610+ "all,any"
1611+ (S.fold
1612+ ((,) <$> FL.all (<= (value + 1)) <*>
1613+ FL.any (> (value + 1))))
1614+ , benchIOSink
1615+ value
1616+ "sum,length"
1617+ (S.fold ((,) <$> FL.sum <*> FL.length))
1618+ ]
1619+ ]
1620+ ]
1621+
1622+o_1_space_serial_pipes :: Int -> [Benchmark]
1623+o_1_space_serial_pipes value =
1624+ [ bgroup
1625+ "serially"
1626+ [ bgroup
1627+ "pipes"
1628+ [ benchIOSink value "mapM" (transformMapM serially 1)
1629+ , benchIOSink
1630+ value
1631+ "compose"
1632+ (transformComposeMapM serially 1)
1633+ , benchIOSink value "tee" (transformTeeMapM serially 1)
1634+ , benchIOSink value "zip" (transformZipMapM serially 1)
1635+ ]
1636+ ]
1637+ ]
1638+
1639+o_1_space_serial_pipesX4 :: Int -> [Benchmark]
1640+o_1_space_serial_pipesX4 value =
1641+ [ bgroup
1642+ "serially"
1643+ [ bgroup
1644+ "pipesX4"
1645+ [ benchIOSink value "mapM" (transformMapM serially 4)
1646+ , benchIOSink
1647+ value
1648+ "compose"
1649+ (transformComposeMapM serially 4)
1650+ , benchIOSink value "tee" (transformTeeMapM serially 4)
1651+ , benchIOSink value "zip" (transformZipMapM serially 4)
1652+ ]
1653+ ]
1654+ ]
1655+
1656+
1657+o_1_space_serial_transformer :: Int -> [Benchmark]
1658+o_1_space_serial_transformer value =
1659+ [ bgroup
1660+ "serially"
1661+ [ bgroup
1662+ "transformer"
1663+ [ benchIOSrc serially "evalState" (evalStateT value)
1664+ , benchIOSrc serially "withState" (withState value)
1665+ ]
1666+ ]
1667+ ]
1668+
1669+o_1_space_serial_transformation :: Int -> [Benchmark]
1670+o_1_space_serial_transformation value =
1671+ [ bgroup
1672+ "serially"
1673+ [ bgroup
1674+ "transformation"
1675+ [ benchIOSink value "scanl" (scan 1)
1676+ , benchIOSink value "scanl1'" (scanl1' 1)
1677+ , benchIOSink value "map" (map 1)
1678+ , benchIOSink value "fmap" (fmap 1)
1679+ , benchIOSink value "mapM" (mapM serially 1)
1680+ , benchIOSink value "mapMaybe" (mapMaybe 1)
1681+ , benchIOSink value "mapMaybeM" (mapMaybeM 1)
1682+ , bench "sequence" $
1683+ nfIO $
1684+ randomRIO (1, 1000) >>= \n ->
1685+ sequence serially (sourceUnfoldrMAction value n)
1686+ , benchIOSink value "findIndices" (findIndices value 1)
1687+ , benchIOSink value "elemIndices" (elemIndices value 1)
1688+ , benchIOSink value "foldrS" (foldrS 1)
1689+ , benchIOSink value "foldrSMap" (foldrSMap 1)
1690+ , benchIOSink value "foldrT" (foldrT 1)
1691+ , benchIOSink value "foldrTMap" (foldrTMap 1)
1692+ , benchIOSink value "tap" (tap 1)
1693+ , benchIOSink value "tapRate 1 second" (tapRate 1)
1694+ , benchIOSink value "pollCounts 1 second" (pollCounts 1)
1695+ , benchIOSink value "tapAsync" (tapAsync 1)
1696+ , benchIOSink value "tapAsyncS" (tapAsyncS 1)
1697+ ]
1698+ ]
1699+ ]
1700+
1701+o_1_space_serial_transformationX4 :: Int -> [Benchmark]
1702+o_1_space_serial_transformationX4 value =
1703+ [ bgroup
1704+ "serially"
1705+ [ bgroup
1706+ "transformationX4"
1707+ [ benchIOSink value "scan" (scan 4)
1708+ , benchIOSink value "scanl1'" (scanl1' 4)
1709+ , benchIOSink value "map" (map 4)
1710+ , benchIOSink value "fmap" (fmap 4)
1711+ , benchIOSink value "mapM" (mapM serially 4)
1712+ , benchIOSink value "mapMaybe" (mapMaybe 4)
1713+ , benchIOSink value "mapMaybeM" (mapMaybeM 4)
1714+ -- , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
1715+ -- sequence serially (sourceUnfoldrMAction n)
1716+ , benchIOSink value "findIndices" (findIndices value 4)
1717+ , benchIOSink value "elemIndices" (elemIndices value 4)
1718+ ]
1719+ ]
1720+ ]
1721+
1722+o_1_space_serial_filtering :: Int -> [Benchmark]
1723+o_1_space_serial_filtering value =
1724+ [ bgroup
1725+ "serially"
1726+ [ bgroup
1727+ "filtering"
1728+ [ benchIOSink value "filter-even" (filterEven 1)
1729+ , benchIOSink value "filter-all-out" (filterAllOut value 1)
1730+ , benchIOSink value "filter-all-in" (filterAllIn value 1)
1731+ , benchIOSink value "take-all" (takeAll value 1)
1732+ , benchIOSink
1733+ value
1734+ "takeByTime-all"
1735+ (takeByTime (NanoSecond64 maxBound) 1)
1736+ , benchIOSink value "takeWhile-true" (takeWhileTrue value 1)
1737+ --, benchIOSink value "takeWhileM-true" (takeWhileMTrue 1)
1738+ -- "drop-one" is dual to "last"
1739+ , benchIOSink value "drop-one" (dropOne 1)
1740+ , benchIOSink value "drop-all" (dropAll value 1)
1741+ , benchIOSink
1742+ value
1743+ "dropByTime-all"
1744+ (dropByTime (NanoSecond64 maxBound) 1)
1745+ , benchIOSink value "dropWhile-true" (dropWhileTrue value 1)
1746+ --, benchIOSink value "dropWhileM-true" (dropWhileMTrue 1)
1747+ , benchIOSink
1748+ value
1749+ "dropWhile-false"
1750+ (dropWhileFalse value 1)
1751+ , benchIOSink value "deleteBy" (deleteBy value 1)
1752+ , benchIOSink value "intersperse" (intersperse value 1)
1753+ , benchIOSink value "insertBy" (insertBy value 1)
1754+ ]
1755+ ]
1756+ ]
1757+
1758+o_1_space_serial_filteringX4 :: Int -> [Benchmark]
1759+o_1_space_serial_filteringX4 value =
1760+ [ bgroup
1761+ "serially"
1762+ [ bgroup
1763+ "filteringX4"
1764+ [ benchIOSink value "filter-even" (filterEven 4)
1765+ , benchIOSink value "filter-all-out" (filterAllOut value 4)
1766+ , benchIOSink value "filter-all-in" (filterAllIn value 4)
1767+ , benchIOSink value "take-all" (takeAll value 4)
1768+ , benchIOSink value "takeWhile-true" (takeWhileTrue value 4)
1769+ --, benchIOSink value "takeWhileM-true" (takeWhileMTrue 4)
1770+ , benchIOSink value "drop-one" (dropOne 4)
1771+ , benchIOSink value "drop-all" (dropAll value 4)
1772+ , benchIOSink value "dropWhile-true" (dropWhileTrue value 4)
1773+ --, benchIOSink value "dropWhileM-true" (dropWhileMTrue 4)
1774+ , benchIOSink
1775+ value
1776+ "dropWhile-false"
1777+ (dropWhileFalse value 4)
1778+ , benchIOSink value "deleteBy" (deleteBy value 4)
1779+ , benchIOSink value "intersperse" (intersperse value 4)
1780+ , benchIOSink value "insertBy" (insertBy value 4)
1781+ ]
1782+ ]
1783+ ]
1784+
1785+
1786+o_1_space_serial_joining :: Int -> [Benchmark]
1787+o_1_space_serial_joining value =
1788+ [ bgroup
1789+ "serially"
1790+ [ bgroup
1791+ "joining"
1792+ [ benchIOSrc1 "zip (2,x/2)" (zip (value `div` 2))
1793+ , benchIOSrc1 "zipM (2,x/2)" (zipM (value `div` 2))
1794+ , benchIOSrc1 "mergeBy (2,x/2)" (mergeBy (value `div` 2))
1795+ , benchIOSrc1 "serial (2,x/2)" (serial2 (value `div` 2))
1796+ , benchIOSrc1 "append (2,x/2)" (append2 (value `div` 2))
1797+ , benchIOSrc1 "serial (2,2,x/4)" (serial4 (value `div` 4))
1798+ , benchIOSrc1 "append (2,2,x/4)" (append4 (value `div` 4))
1799+ , benchIOSrc1 "wSerial (2,x/2)" (wSerial2 value) -- XXX Move this elsewhere?
1800+ , benchIOSrc1 "interleave (2,x/2)" (interleave2 value)
1801+ , benchIOSrc1 "roundRobin (2,x/2)" (roundRobin2 value)
1802+ ]
1803+ ]
1804+ ]
1805+
1806+
1807+o_1_space_serial_concatFoldable :: Int -> [Benchmark]
1808+o_1_space_serial_concatFoldable value =
1809+ [ bgroup
1810+ "serially"
1811+ [ bgroup
1812+ "concat-foldable"
1813+ [ benchIOSrc
1814+ serially
1815+ "foldMapWith"
1816+ (sourceFoldMapWith value)
1817+ , benchIOSrc
1818+ serially
1819+ "foldMapWithM"
1820+ (sourceFoldMapWithM value)
1821+ , benchIOSrc serially "foldMapM" (sourceFoldMapM value)
1822+ , benchIOSrc
1823+ serially
1824+ "foldWithConcatMapId"
1825+ (sourceConcatMapId value)
1826+ ]
1827+ ]
1828+ ]
1829+
1830+o_1_space_serial_concatSerial :: Int -> [Benchmark]
1831+o_1_space_serial_concatSerial value =
1832+ [ bgroup
1833+ "serially"
1834+ [ bgroup
1835+ "concat-serial"
1836+ [ benchIOSrc1
1837+ "concatMapPure (2,x/2)"
1838+ (concatMapPure 2 (value `div` 2))
1839+ , benchIOSrc1
1840+ "concatMap (2,x/2)"
1841+ (concatMap 2 (value `div` 2))
1842+ , benchIOSrc1
1843+ "concatMap (x/2,2)"
1844+ (concatMap (value `div` 2) 2)
1845+ , benchIOSrc1
1846+ "concatMapRepl (x/4,4)"
1847+ (concatMapRepl4xN value)
1848+ , benchIOSrc1
1849+ "concatUnfoldRepl (x/4,4)"
1850+ (concatUnfoldRepl4xN value)
1851+ , benchIOSrc1
1852+ "concatMapWithSerial (2,x/2)"
1853+ (concatMapWithSerial 2 (value `div` 2))
1854+ , benchIOSrc1
1855+ "concatMapWithSerial (x/2,2)"
1856+ (concatMapWithSerial (value `div` 2) 2)
1857+ , benchIOSrc1
1858+ "concatMapWithAppend (2,x/2)"
1859+ (concatMapWithAppend 2 (value `div` 2))
1860+ ]
1861+ ]
1862+ ]
1863+
1864+
1865+o_1_space_serial_outerProductStreams :: Int -> [Benchmark]
1866+o_1_space_serial_outerProductStreams value =
1867+ [ bgroup
1868+ "serially"
1869+ [ bgroup
1870+ "outer-product-streams"
1871+ [ benchIO "toNullAp" $ Nested.toNullAp value serially
1872+ , benchIO "toNull" $ Nested.toNull value serially
1873+ , benchIO "toNull3" $ Nested.toNull3 value serially
1874+ , benchIO "filterAllOut" $ Nested.filterAllOut value serially
1875+ , benchIO "filterAllIn" $ Nested.filterAllIn value serially
1876+ , benchIO "filterSome" $ Nested.filterSome value serially
1877+ , benchIO "breakAfterSome" $
1878+ Nested.breakAfterSome value serially
1879+ ]
1880+ ]
1881+ ]
1882+
1883+
1884+o_1_space_serial_outerProductUnfolds :: Int -> [Benchmark]
1885+o_1_space_serial_outerProductUnfolds value =
1886+ [ bgroup
1887+ "serially"
1888+ [ bgroup
1889+ "outer-product-unfolds"
1890+ [ benchIO "toNull" $ NestedUnfold.toNull value
1891+ , benchIO "toNull3" $ NestedUnfold.toNull3 value
1892+ , benchIO "concat" $ NestedUnfold.concat value
1893+ , benchIO "filterAllOut" $ NestedUnfold.filterAllOut value
1894+ , benchIO "filterAllIn" $ NestedUnfold.filterAllIn value
1895+ , benchIO "filterSome" $ NestedUnfold.filterSome value
1896+ , benchIO "breakAfterSome" $ NestedUnfold.breakAfterSome value
1897+ ]
1898+ ]
1899+ ]
1900+
1901+
1902+o_1_space_serial_mixed :: Int -> [Benchmark]
1903+o_1_space_serial_mixed value =
1904+ [ bgroup
1905+ "serially"
1906+ -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
1907+ -- library. If scan/fold followed by a map is efficient enough we may not
1908+ -- need monolithic implementations of these.
1909+ [ bgroup
1910+ "mixed"
1911+ [ benchIOSink value "scanl-map" (scanMap 1)
1912+ , benchIOSink value "foldl-map" foldl'ReduceMap
1913+ , benchIOSink value "sum-product-fold" sumProductFold
1914+ , benchIOSink value "sum-product-scan" sumProductScan
1915+ ]
1916+ ]
1917+ ]
1918+
1919+o_1_space_serial_mixedX4 :: Int -> [Benchmark]
1920+o_1_space_serial_mixedX4 value =
1921+ [ bgroup
1922+ "serially"
1923+ [ bgroup
1924+ "mixedX4"
1925+ [ benchIOSink value "scan-map" (scanMap 4)
1926+ , benchIOSink value "drop-map" (dropMap 4)
1927+ , benchIOSink value "drop-scan" (dropScan 4)
1928+ , benchIOSink value "take-drop" (takeDrop value 4)
1929+ , benchIOSink value "take-scan" (takeScan value 4)
1930+ , benchIOSink value "take-map" (takeMap value 4)
1931+ , benchIOSink value "filter-drop" (filterDrop value 4)
1932+ , benchIOSink value "filter-take" (filterTake value 4)
1933+ , benchIOSink value "filter-scan" (filterScan 4)
1934+ , benchIOSink value "filter-scanl1" (filterScanl1 4)
1935+ , benchIOSink value "filter-map" (filterMap value 4)
1936+ ]
1937+ ]
1938+ ]
1939+
1940+o_1_space_wSerial_transformation :: Int -> [Benchmark]
1941+o_1_space_wSerial_transformation value =
1942+ [ bgroup
1943+ "wSerially"
1944+ [ bgroup
1945+ "transformation"
1946+ [benchIOSink value "fmap" $ fmap' wSerially 1]
1947+ ]
1948+ ]
1949+
1950+o_1_space_wSerial_concatMap :: Int -> [Benchmark]
1951+o_1_space_wSerial_concatMap value =
1952+ [ bgroup
1953+ "wSerially"
1954+ [ bgroup
1955+ "concatMap"
1956+ [ benchIOSrc1
1957+ "concatMapWithWSerial (2,x/2)"
1958+ (concatMapWithWSerial 2 (value `div` 2))
1959+ , benchIOSrc1
1960+ "concatMapWithWSerial (x/2,2)"
1961+ (concatMapWithWSerial (value `div` 2) 2)
1962+ ]
1963+ ]
1964+ ]
1965+
1966+o_1_space_wSerial_outerProduct :: Int -> [Benchmark]
1967+o_1_space_wSerial_outerProduct value =
1968+ [ bgroup
1969+ "wSerially"
1970+ [ bgroup
1971+ "outer-product"
1972+ [ benchIO "toNullAp" $ Nested.toNullAp value wSerially
1973+ , benchIO "toNull" $ Nested.toNull value wSerially
1974+ , benchIO "toNull3" $ Nested.toNull3 value wSerially
1975+ , benchIO "filterAllOut" $ Nested.filterAllOut value wSerially
1976+ , benchIO "filterAllIn" $ Nested.filterAllIn value wSerially
1977+ , benchIO "filterSome" $ Nested.filterSome value wSerially
1978+ , benchIO "breakAfterSome" $
1979+ Nested.breakAfterSome value wSerially
1980+ ]
1981+ ]
1982+ ]
1983+
1984+o_1_space_zipSerial_transformation :: Int -> [Benchmark]
1985+o_1_space_zipSerial_transformation value =
1986+ [ bgroup
1987+ "zipSerially"
1988+ [ bgroup
1989+ "transformation"
1990+ [benchIOSink value "fmap" $ fmap' zipSerially 1]
1991+ -- XXX needs fixing
1992+ {-
1993+ , bgroup "outer-product"
1994+ [ benchIO "toNullAp" $ Nested.toNullAp value zipSerially
1995+ ]
1996+ -}
1997+ ]
1998+ ]
benchmark/streamly-benchmarks.cabal−1
@@ -137,7 +137,6 @@ library lib-prelude
137137 hs-source-dirs: lib, .
138138 exposed-modules:
139139 Streamly.Benchmark.Prelude
140− , Streamly.Benchmark.Groups
141140 other-modules: Streamly.Benchmark.Common
142141 , NestedOps
143142 , NestedUnfoldOps