2#if __GLASGOW_HASKELL__ >= 800
3{-# OPTIONS_GHC -Wno-orphans #-}
8-- Copyright : (c) 2018 Harendra Kumar
11-- Maintainer : streamly@composewell.com
13import Control.DeepSeq (NFData(..), deepseq)
14import Data.Functor.Identity (Identity, runIdentity)
15import Data.Monoid (Last(..))
16import System.Random (randomRIO)
18import Common (parseCLIOpts)
20import qualified GHC.Exts as GHC
21import qualified Streamly.Benchmark.Prelude as Ops
24import qualified Streamly.Data.Fold as FL
25import qualified Streamly.Memory.Array as A
26import qualified Streamly.Prelude as S
27import qualified Streamly.Internal.Data.Sink as Sink
29import Streamly.Internal.Data.Time.Units
30import qualified Streamly.Internal.Memory.Array as IA
31import qualified Streamly.Internal.Data.Fold as IFL
32import qualified Streamly.Internal.Prelude as IP
33import qualified Streamly.Internal.Data.Pipe as Pipe
37-------------------------------------------------------------------------------
39-------------------------------------------------------------------------------
41#if !MIN_VERSION_deepseq(1,4,3)
42instance NFData Ordering where rnf = (`seq` ())
45-- We need a monadic bind here to make sure that the function f does not get
46-- completely optimized out by the compiler in some cases.
48-- | Takes a fold method, and uses it with a default source.
49{-# INLINE benchIOSink #-}
51 :: (IsStream t, NFData b)
52 => Int -> String -> (t IO Int -> IO b) -> Benchmark
53benchIOSink value name f = bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.source value
55{-# INLINE benchHoistSink #-}
57 :: (IsStream t, NFData b)
58 => Int -> String -> (t Identity Int -> IO b) -> Benchmark
59benchHoistSink value name f =
60 bench name $ nfIO $ randomRIO (1,1) >>= f . Ops.sourceUnfoldr value
62-- XXX once we convert all the functions to use this we can rename this to
64{-# INLINE benchIOSink1 #-}
65benchIOSink1 :: NFData b => String -> (Int -> IO b) -> Benchmark
66benchIOSink1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
68-- XXX We should be using sourceUnfoldrM for fair comparison with IO monad, but
69-- we can't use it as it requires MonadAsync constraint.
70{-# INLINE benchIdentitySink #-}
72 :: (IsStream t, NFData b)
73 => Int -> String -> (t Identity Int -> Identity b) -> Benchmark
74benchIdentitySink value name f = bench name $ nf (f . Ops.sourceUnfoldr value) 1
76-- | Takes a source, and uses it with a default drain/fold method.
77{-# INLINE benchIOSrc #-}
79 :: (t IO a -> SerialT IO a)
84 bench name $ nfIO $ randomRIO (1,1) >>= Ops.toNull t . f
86{-# INLINE benchIOSrc1 #-}
87benchIOSrc1 :: String -> (Int -> IO ()) -> Benchmark
88benchIOSrc1 name f = bench name $ nfIO $ randomRIO (1,1) >>= f
90{-# INLINE benchPure #-}
91benchPure :: NFData b => String -> (Int -> a) -> (a -> b) -> Benchmark
92benchPure name src f = bench name $ nfIO $ randomRIO (1,1) >>= return . f . src
94{-# INLINE benchPureSink #-}
95benchPureSink :: NFData b => Int -> String -> (SerialT Identity Int -> b) -> Benchmark
96benchPureSink value name f = benchPure name (Ops.sourceUnfoldr value) f
98-- XXX once we convert all the functions to use this we can rename this to
100{-# INLINE benchPureSink1 #-}
101benchPureSink1 :: NFData b => String -> (Int -> Identity b) -> Benchmark
102benchPureSink1 name f =
103 bench name $ nfIO $ randomRIO (1,1) >>= return . runIdentity . f
105{-# INLINE benchPureSinkIO #-}
108 => Int -> String -> (SerialT Identity Int -> IO b) -> Benchmark
109benchPureSinkIO value name f =
110 bench name $ nfIO $ randomRIO (1, 1) >>= f . Ops.sourceUnfoldr value
112{-# INLINE benchPureSrc #-}
113benchPureSrc :: String -> (Int -> SerialT Identity a) -> Benchmark
114benchPureSrc name src = benchPure name src (runIdentity . S.drain)
116mkString :: Int -> String
117mkString value = "fromList [1" ++ concat (replicate value ",1") ++ "]"
119mkListString :: Int -> String
120mkListString value = "[1" ++ concat (replicate value ",1") ++ "]"
122mkList :: Int -> [Int]
123mkList value = [1..value]
125defaultStreamSize :: Int
126defaultStreamSize = 100000
130 -- XXX Fix indentation
131 (value, cfg, benches) <- parseCLIOpts defaultStreamSize
132 value `seq` runMode (mode cfg) cfg benches
135 [ benchPureSink value "id" id
136 , benchPureSink1 "eqBy" (Ops.eqByPure value)
137 , benchPureSink value "==" Ops.eqInstance
138 , benchPureSink value "/=" Ops.eqInstanceNotEq
139 , benchPureSink1 "cmpBy" (Ops.cmpByPure value)
140 , benchPureSink value "<" Ops.ordInstance
141 , benchPureSink value "min" Ops.ordInstanceMin
142 , benchPureSrc "IsList.fromList" (Ops.sourceIsList value)
143 -- length is used to check for foldr/build fusion
144 , benchPureSink value "length . IsList.toList" (length . GHC.toList)
145 , benchPureSrc "IsString.fromString" (Ops.sourceIsString value)
146 , benchPureSink value "showsPrec pure streams" Ops.showInstance
147 , benchPureSink value "foldl'" Ops.pureFoldl'
148 , benchPureSink value "foldable/foldl'" Ops.foldableFoldl'
150 , bgroup "generation"
151 [ -- Most basic, barely stream continuations running
152 benchIOSrc serially "unfoldr" (Ops.sourceUnfoldr value)
153 , benchIOSrc serially "unfoldrM" (Ops.sourceUnfoldrM value)
154 , benchIOSrc serially "intFromTo" (Ops.sourceIntFromTo value)
155 , benchIOSrc serially "intFromThenTo" (Ops.sourceIntFromThenTo value)
156 , benchIOSrc serially "integerFromStep" (Ops.sourceIntegerFromStep value)
157 , benchIOSrc serially "fracFromThenTo" (Ops.sourceFracFromThenTo value)
158 , benchIOSrc serially "fracFromTo" (Ops.sourceFracFromTo value)
159 , benchIOSrc serially "fromList" (Ops.sourceFromList value)
160 , benchIOSrc serially "fromListM" (Ops.sourceFromListM value)
161 -- These are essentially cons and consM
162 , benchIOSrc serially "fromFoldable" (Ops.sourceFromFoldable value)
163 , benchIOSrc serially "fromFoldableM" (Ops.sourceFromFoldableM value)
165 -- Compare this with takeAll
166 , bench "currentTime: 0.00001 sec granularity" $ nfIO $ Ops.currentTime value 0.00001
167 , bench "currentTime: 0.0001 sec granularity" $ nfIO $ Ops.currentTime value 0.0001
168 , bench "currentTime: 0.001 sec granularity" $ nfIO $ Ops.currentTime value 0.001
169 , bench "currentTime: 0.01 sec granularity" $ nfIO $ Ops.currentTime value 0.01
172 , bgroup "elimination"
176 benchIOSink value "foldl'" Ops.foldl'Reduce
177 , benchIOSink value "foldl1'" Ops.foldl1'Reduce
178 , benchIOSink value "foldlM'" Ops.foldlM'Reduce
182 benchIdentitySink value "foldl'" Ops.foldl'Reduce
183 , benchIdentitySink value "foldl1'" Ops.foldl1'Reduce
184 , benchIdentitySink value "foldlM'" Ops.foldlM'Reduce
190 [ benchIdentitySink value "foldrM" Ops.foldrMBuild
193 , benchIOSink value "uncons" Ops.uncons
194 , benchIOSink value "toNull" $ Ops.toNull serially
195 , benchIOSink value "mapM_" Ops.mapM_
197 , benchIOSink value "init" Ops.init
199 -- this is too low and causes all benchmarks reported in ns
200 -- , benchIOSink value "head" Ops.head
201 , benchIOSink value "last" Ops.last
202 -- , benchIOSink value "lookup" Ops.lookup
203 , benchIOSink value "find" (Ops.find value)
204 , benchIOSink value "findIndex" (Ops.findIndex value)
205 , benchIOSink value "elemIndex" (Ops.elemIndex value)
207 -- this is too low and causes all benchmarks reported in ns
208 -- , benchIOSink value "null" Ops.null
209 , benchIOSink value "elem" (Ops.elem value)
210 , benchIOSink value "notElem" (Ops.notElem value)
211 , benchIOSink value "all" (Ops.all value)
212 , benchIOSink value "any" (Ops.any value)
213 , benchIOSink value "and" (Ops.and value)
214 , benchIOSink value "or" (Ops.or value)
216 , benchIOSink value "length" Ops.length
217 , benchHoistSink value "length . generally" (Ops.length . IP.generally)
218 , benchIOSink value "sum" Ops.sum
219 , benchIOSink value "product" Ops.product
221 , benchIOSink value "maximumBy" Ops.maximumBy
222 , benchIOSink value "maximum" Ops.maximum
223 , benchIOSink value "minimumBy" Ops.minimumBy
224 , benchIOSink value "minimum" Ops.minimum
228 [ benchIOSink value "drain" (S.fold FL.drain)
229 , benchIOSink value "drainN" (S.fold (IFL.drainN value))
230 , benchIOSink value "drainWhileTrue" (S.fold (IFL.drainWhile $ (<=) (value + 1)))
231 , benchIOSink value "drainWhileFalse" (S.fold (IFL.drainWhile $ (>=) (value + 1)))
232 , benchIOSink value "sink" (S.fold $ Sink.toFold Sink.drain)
233 , benchIOSink value "last" (S.fold FL.last)
234 , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
235 , benchIOSink value "lastN.10" (S.fold (IA.lastN 10))
236 , benchIOSink value "length" (S.fold FL.length)
237 , benchIOSink value "sum" (S.fold FL.sum)
238 , benchIOSink value "product" (S.fold FL.product)
239 , benchIOSink value "maximumBy" (S.fold (FL.maximumBy compare))
240 , benchIOSink value "maximum" (S.fold FL.maximum)
241 , benchIOSink value "minimumBy" (S.fold (FL.minimumBy compare))
242 , benchIOSink value "minimum" (S.fold FL.minimum)
243 , benchIOSink value "mean" (\s -> S.fold FL.mean (S.map (fromIntegral :: Int -> Double) s))
244 , benchIOSink value "variance" (\s -> S.fold FL.variance (S.map (fromIntegral :: Int -> Double) s))
245 , benchIOSink value "stdDev" (\s -> S.fold FL.stdDev (S.map (fromIntegral :: Int -> Double) s))
247 , benchIOSink value "mconcat" (S.fold FL.mconcat . (S.map (Last . Just)))
248 , benchIOSink value "foldMap" (S.fold (FL.foldMap (Last . Just)))
250 , benchIOSink value "index" (S.fold (FL.index (value + 1)))
251 , benchIOSink value "head" (S.fold FL.head)
252 , benchIOSink value "find" (S.fold (FL.find (== (value + 1))))
253 , benchIOSink value "findIndex" (S.fold (FL.findIndex (== (value + 1))))
254 , benchIOSink value "elemIndex" (S.fold (FL.elemIndex (value + 1)))
256 , benchIOSink value "null" (S.fold FL.null)
257 , benchIOSink value "elem" (S.fold (FL.elem (value + 1)))
258 , benchIOSink value "notElem" (S.fold (FL.notElem (value + 1)))
259 , benchIOSink value "all" (S.fold (FL.all (<= (value + 1))))
260 , benchIOSink value "any" (S.fold (FL.any (> (value + 1))))
261 , benchIOSink value "and" (\s -> S.fold FL.and (S.map (<= (value + 1)) s))
262 , benchIOSink value "or" (\s -> S.fold FL.or (S.map (> (value + 1)) s))
264 , bgroup "fold-multi-stream"
265 [ benchIOSink1 "eqBy" (Ops.eqBy value)
266 , benchIOSink1 "cmpBy" (Ops.cmpBy value)
267 , benchIOSink value "isPrefixOf" Ops.isPrefixOf
268 , benchIOSink value "isSubsequenceOf" Ops.isSubsequenceOf
269 , benchIOSink value "stripPrefix" Ops.stripPrefix
271 , bgroup "folds-transforms"
272 [ benchIOSink value "drain" (S.fold FL.drain)
273 , benchIOSink value "lmap" (S.fold (IFL.lmap (+1) FL.drain))
274 , benchIOSink value "pipe-mapM"
275 (S.fold (IFL.transform (Pipe.mapM (\x -> return $ x + 1)) FL.drain))
277 , bgroup "folds-compositions" -- Applicative
279 benchIOSink value "all,any" (S.fold ((,) <$> FL.all (<= (value + 1))
280 <*> FL.any (> (value + 1))))
281 , benchIOSink value "sum,length" (S.fold ((,) <$> FL.sum <*> FL.length))
284 [ benchIOSink value "mapM" (Ops.transformMapM serially 1)
285 , benchIOSink value "compose" (Ops.transformComposeMapM serially 1)
286 , benchIOSink value "tee" (Ops.transformTeeMapM serially 1)
287 , benchIOSink value "zip" (Ops.transformZipMapM serially 1)
290 [ benchIOSink value "mapM" (Ops.transformMapM serially 4)
291 , benchIOSink value "compose" (Ops.transformComposeMapM serially 4)
292 , benchIOSink value "tee" (Ops.transformTeeMapM serially 4)
293 , benchIOSink value "zip" (Ops.transformZipMapM serially 4)
295 , bgroup "transformer"
296 [ benchIOSrc serially "evalState" (Ops.evalStateT value)
297 , benchIOSrc serially "withState" (Ops.withState value)
299 , bgroup "transformation"
300 [ benchIOSink value "scanl" (Ops.scan 1)
301 , benchIOSink value "scanl1'" (Ops.scanl1' 1)
302 , benchIOSink value "map" (Ops.map 1)
303 , benchIOSink value "fmap" (Ops.fmap 1)
304 , benchIOSink value "mapM" (Ops.mapM serially 1)
305 , benchIOSink value "mapMaybe" (Ops.mapMaybe 1)
306 , benchIOSink value "mapMaybeM" (Ops.mapMaybeM 1)
307 , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
308 Ops.sequence serially (Ops.sourceUnfoldrMAction value n)
309 , benchIOSink value "findIndices" (Ops.findIndices value 1)
310 , benchIOSink value "elemIndices" (Ops.elemIndices value 1)
311 , benchIOSink value "foldrS" (Ops.foldrS 1)
312 , benchIOSink value "foldrSMap" (Ops.foldrSMap 1)
313 , benchIOSink value "foldrT" (Ops.foldrT 1)
314 , benchIOSink value "foldrTMap" (Ops.foldrTMap 1)
315 , benchIOSink value "tap" (Ops.tap 1)
316 , benchIOSink value "tapRate 1 second" (Ops.tapRate 1)
317 , benchIOSink value "pollCounts 1 second" (Ops.pollCounts 1)
318 , benchIOSink value "tapAsync" (Ops.tapAsync 1)
319 , benchIOSink value "tapAsyncS" (Ops.tapAsyncS 1)
321 , bgroup "transformationX4"
322 [ benchIOSink value "scan" (Ops.scan 4)
323 , benchIOSink value "scanl1'" (Ops.scanl1' 4)
324 , benchIOSink value "map" (Ops.map 4)
325 , benchIOSink value "fmap" (Ops.fmap 4)
326 , benchIOSink value "mapM" (Ops.mapM serially 4)
327 , benchIOSink value "mapMaybe" (Ops.mapMaybe 4)
328 , benchIOSink value "mapMaybeM" (Ops.mapMaybeM 4)
329 -- , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
330 -- Ops.sequence serially (Ops.sourceUnfoldrMAction n)
331 , benchIOSink value "findIndices" (Ops.findIndices value 4)
332 , benchIOSink value "elemIndices" (Ops.elemIndices value 4)
335 [ benchIOSink value "filter-even" (Ops.filterEven 1)
336 , benchIOSink value "filter-all-out" (Ops.filterAllOut value 1)
337 , benchIOSink value "filter-all-in" (Ops.filterAllIn value 1)
339 , benchIOSink value "take-all" (Ops.takeAll value 1)
340 , benchIOSink value "takeByTime-all"
341 (Ops.takeByTime (NanoSecond64 maxBound) 1)
342 , benchIOSink value "takeWhile-true" (Ops.takeWhileTrue value 1)
343 --, benchIOSink value "takeWhileM-true" (Ops.takeWhileMTrue 1)
345 -- "drop-one" is dual to "last"
346 , benchIOSink value "drop-one" (Ops.dropOne 1)
347 , benchIOSink value "drop-all" (Ops.dropAll value 1)
348 , benchIOSink value "dropByTime-all"
349 (Ops.dropByTime (NanoSecond64 maxBound) 1)
350 , benchIOSink value "dropWhile-true" (Ops.dropWhileTrue value 1)
351 --, benchIOSink value "dropWhileM-true" (Ops.dropWhileMTrue 1)
352 , benchIOSink value "dropWhile-false" (Ops.dropWhileFalse value 1)
354 , benchIOSink value "deleteBy" (Ops.deleteBy value 1)
355 , benchIOSink value "intersperse" (Ops.intersperse value 1)
356 , benchIOSink value "insertBy" (Ops.insertBy value 1)
358 , bgroup "filteringX4"
359 [ benchIOSink value "filter-even" (Ops.filterEven 4)
360 , benchIOSink value "filter-all-out" (Ops.filterAllOut value 4)
361 , benchIOSink value "filter-all-in" (Ops.filterAllIn value 4)
362 , benchIOSink value "take-all" (Ops.takeAll value 4)
363 , benchIOSink value "takeWhile-true" (Ops.takeWhileTrue value 4)
364 --, benchIOSink value "takeWhileM-true" (Ops.takeWhileMTrue 4)
365 , benchIOSink value "drop-one" (Ops.dropOne 4)
366 , benchIOSink value "drop-all" (Ops.dropAll value 4)
367 , benchIOSink value "dropWhile-true" (Ops.dropWhileTrue value 4)
368 --, benchIOSink value "dropWhileM-true" (Ops.dropWhileMTrue 4)
369 , benchIOSink value "dropWhile-false" (Ops.dropWhileFalse value 4)
370 , benchIOSink value "deleteBy" (Ops.deleteBy value 4)
371 , benchIOSink value "intersperse" (Ops.intersperse value 4)
372 , benchIOSink value "insertBy" (Ops.insertBy value 4)
375 [ benchIOSrc1 "zip (2,x/2)" (Ops.zip (value `div` 2))
376 , benchIOSrc1 "zipM (2,x/2)" (Ops.zipM (value `div` 2))
377 , benchIOSrc1 "mergeBy (2,x/2)" (Ops.mergeBy (value `div` 2))
378 , benchIOSrc1 "serial (2,x/2)" (Ops.serial2 (value `div` 2))
379 , benchIOSrc1 "append (2,x/2)" (Ops.append2 (value `div` 2))
380 , benchIOSrc1 "serial (2,2,x/4)" (Ops.serial4 (value `div` 4))
381 , benchIOSrc1 "append (2,2,x/4)" (Ops.append4 (value `div` 4))
382 , benchIOSrc1 "wSerial (2,x/2)" (Ops.wSerial2 value)
383 , benchIOSrc1 "interleave (2,x/2)" (Ops.interleave2 value)
384 , benchIOSrc1 "roundRobin (2,x/2)" (Ops.roundRobin2 value)
386 , bgroup "concat-foldable"
387 [ benchIOSrc serially "foldMapWith" (Ops.sourceFoldMapWith value)
388 , benchIOSrc serially "foldMapWithM" (Ops.sourceFoldMapWithM value)
389 , benchIOSrc serially "foldMapM" (Ops.sourceFoldMapM value)
390 , benchIOSrc serially "foldWithConcatMapId" (Ops.sourceConcatMapId value)
392 , bgroup "concat-serial"
393 [ benchIOSrc1 "concatMapPure (2,x/2)" (Ops.concatMapPure 2 (value `div` 2))
394 , benchIOSrc1 "concatMap (2,x/2)" (Ops.concatMap 2 (value `div` 2))
395 , benchIOSrc1 "concatMap (x/2,2)" (Ops.concatMap (value `div` 2) 2)
396 , benchIOSrc1 "concatMapRepl (x/4,4)" (Ops.concatMapRepl4xN value)
397 , benchIOSrc1 "concatUnfoldRepl (x/4,4)" (Ops.concatUnfoldRepl4xN value)
399 , benchIOSrc1 "concatMapWithSerial (2,x/2)"
400 (Ops.concatMapWithSerial 2 (value `div` 2))
401 , benchIOSrc1 "concatMapWithSerial (x/2,2)"
402 (Ops.concatMapWithSerial (value `div` 2) 2)
404 , benchIOSrc1 "concatMapWithAppend (2,x/2)"
405 (Ops.concatMapWithAppend 2 (value `div` 2))
407 , bgroup "concat-interleave"
408 [ benchIOSrc1 "concatMapWithWSerial (2,x/2)"
409 (Ops.concatMapWithWSerial 2 (value `div` 2))
410 , benchIOSrc1 "concatMapWithWSerial (x/2,2)"
411 (Ops.concatMapWithWSerial (value `div` 2) 2)
413 -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
414 -- library. If scan/fold followed by a map is efficient enough we may not
415 -- need monolithic implementations of these.
417 [ benchIOSink value "scanl-map" (Ops.scanMap 1)
418 , benchIOSink value "foldl-map" Ops.foldl'ReduceMap
419 , benchIOSink value "sum-product-fold" Ops.sumProductFold
420 , benchIOSink value "sum-product-scan" Ops.sumProductScan
423 [ benchIOSink value "scan-map" (Ops.scanMap 4)
424 , benchIOSink value "drop-map" (Ops.dropMap 4)
425 , benchIOSink value "drop-scan" (Ops.dropScan 4)
426 , benchIOSink value "take-drop" (Ops.takeDrop value 4)
427 , benchIOSink value "take-scan" (Ops.takeScan value 4)
428 , benchIOSink value "take-map" (Ops.takeMap value 4)
429 , benchIOSink value "filter-drop" (Ops.filterDrop value 4)
430 , benchIOSink value "filter-take" (Ops.filterTake value 4)
431 , benchIOSink value "filter-scan" (Ops.filterScan 4)
432 , benchIOSink value "filter-scanl1" (Ops.filterScanl1 4)
433 , benchIOSink value "filter-map" (Ops.filterMap value 4)
436 [ benchIOSrc serially "mapM" Ops.iterateMapM
437 , benchIOSrc serially "scan(1/100)" Ops.iterateScan
438 , benchIOSrc serially "scanl1(1/100)" Ops.iterateScanl1
439 , benchIOSrc serially "filterEven" Ops.iterateFilterEven
440 , benchIOSrc serially "takeAll" (Ops.iterateTakeAll value)
441 , benchIOSrc serially "dropOne" Ops.iterateDropOne
442 , benchIOSrc serially "dropWhileFalse" (Ops.iterateDropWhileFalse value)
443 , benchIOSrc serially "dropWhileTrue" (Ops.iterateDropWhileTrue value)
447 [ bgroup "transformation"
448 [ benchIOSink value "fmap" $ Ops.fmap' wSerially 1
451 , bgroup "zipSerially"
452 [ bgroup "transformation"
453 [ benchIOSink value "fmap" $ Ops.fmap' zipSerially 1
456 -- Non-streaming operations. We keep these in a spearate group so that we
457 -- can run these conveniently with smaller stream size.
459 -- These are also the operations that programmers should be aware of and
460 -- should avoid using in a streaming application.
462 [ -- Inherently non-streaming operations
464 -- Right folds for reducing are inherently non-streaming as the
465 -- expression needs to be fully built before it can be reduced.
466 benchIOSink value "foldrM/reduce/IO" Ops.foldrMReduce
467 , benchIdentitySink value "foldrM/reduce/Identity" Ops.foldrMReduce
469 -- Left folds for building a structure are inherently non-streaming as
470 -- the structure cannot be lazily consumed until fully built.
471 , benchIOSink value "foldl'/build/IO" Ops.foldl'Build
472 , benchIdentitySink value "foldl'/build/Identity" Ops.foldl'Build
473 , benchIOSink value "foldlM'/build/IO" Ops.foldlM'Build
474 , benchIdentitySink value "foldlM'/build/Identity" Ops.foldlM'Build
476 -- accumulation due to strictness of IO monad
477 , benchIOSink value "foldrM/build/IO" Ops.foldrMBuild
478 , benchPureSinkIO value "traversable/mapM" Ops.traversableMapM
480 -- Converting the stream to a list or pure stream
481 , benchIOSink value "toList" Ops.toList
482 , benchIOSink value "toListRev" Ops.toListRev
483 , benchIOSink value "toStream" (S.fold IP.toStream)
484 , benchIOSink value "toStreamRev" (S.fold IP.toStreamRev)
486 , benchIOSink value "folds/toList" (S.fold FL.toList)
487 , benchIOSink value "folds/toListRevF" (S.fold IFL.toListRevF)
489 -- Converting the stream to an array
490 , benchIOSink value "folds/lastN.Max" (S.fold (IA.lastN (value + 1)))
491 , benchIOSink value "folds/writeN" (S.fold (A.writeN value))
493 -- Reversing/sorting a stream
494 , benchIOSink value "reverse" (Ops.reverse 1)
495 , benchIOSink value "reverse'" (Ops.reverse' 1)
497 -- XXX can these be streaming? Can we have special read/show style type
498 -- classes supporting streaming?
499 , mkString value `deepseq` (bench "readsPrec pure streams" $
500 nf Ops.readInstance (mkString value))
501 , mkString value `deepseq` (bench "readsPrec Haskell lists" $
502 nf Ops.readInstanceList (mkListString value))
503 , mkList value `deepseq` (bench "showPrec Haskell lists" $
504 nf Ops.showInstanceList (mkList value))
506 -- XXX streaming operations that can potentially be fixed
507 , benchPureSink value "foldable/sum" Ops.foldableSum
508 , benchIOSink value "tail" Ops.tail
509 , benchIOSink value "nullHeadTail" Ops.nullHeadTail
510 , benchIOSrc1 "concatUnfoldInterleaveRepl (x/4,4)"
511 (Ops.concatUnfoldInterleaveRepl4xN value)
512 , benchIOSrc1 "concatUnfoldRoundrobinRepl (x/4,4)"
513 (Ops.concatUnfoldRoundrobinRepl4xN 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