@@ -22,19 +22,25 @@ module Main
2222 main
2323 ) where
2424
25+import Control.Applicative ((<|>))
2526import Control.DeepSeq (NFData(..))
27+import Data.Function ((&))
2628import Data.Functor (($>))
2729import Data.Monoid (Sum(..))
2830import GHC.Magic (inline)
2931import GHC.Magic (noinline)
3032import System.IO (Handle)
3133import System.Random (randomRIO)
32−import Streamly.Internal.Data.Parser (ParseError(..))
34+import Streamly.Internal.Data.Fold (Fold(..))
35+import Streamly.Internal.Data.Parser
36+ (ParseError(..), Parser(..), Initial(..), Step(..))
3337import Streamly.Internal.Data.Stream.StreamD (Stream)
3438import Prelude hiding
35− (any, all, take, sequence, sequence_, sequenceA, takeWhile, dropWhile)
39+ (any, all, take, sequence, sequence_, sequenceA, takeWhile, dropWhile, span)
3640
3741import qualified Control.Applicative as AP
42+import qualified Data.Foldable as F
43+import qualified Data.Traversable as TR
3844import qualified Streamly.FileSystem.Handle as Handle
3945import qualified Streamly.Internal.Data.Array as Array
4046import qualified Streamly.Internal.Data.Fold as Fold
@@ -263,16 +269,44 @@ manyTill :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
263269manyTill value =
264270 Stream.parse (PR.manyTill (PR.satisfy (> 0)) (PR.satisfy (== value)) Fold.length)
265271
266−{-# INLINE splitAp #-}
267−splitAp :: Monad m
272+{-# INLINE splitAp2 #-}
273+splitAp2 :: Monad m
268274 => Int -> Stream m Int -> m (Either ParseError ((), ()))
269−splitAp value =
275+splitAp2 value =
270276 Stream.parse
271277 ((,)
272278 <$> PR.dropWhile (<= (value `div` 2))
273279 <*> PR.dropWhile (<= value)
274280 )
275281
282+{-# INLINE splitAp4 #-}
283+splitAp4 :: Monad m
284+ => Int -> Stream m Int -> m (Either ParseError ())
285+splitAp4 value =
286+ Stream.parse
287+ ( (\() () () () -> ())
288+ <$> PR.dropWhile (<= (value * 1 `div` 4))
289+ <*> PR.dropWhile (<= (value * 2 `div` 4))
290+ <*> PR.dropWhile (<= (value * 3 `div` 4))
291+ <*> PR.dropWhile (<= value)
292+ )
293+
294+{-# INLINE splitAp8 #-}
295+splitAp8 :: Monad m
296+ => Int -> Stream m Int -> m (Either ParseError ())
297+splitAp8 value =
298+ Stream.parse
299+ ( (\() () () () () () () () -> ())
300+ <$> PR.dropWhile (<= (value * 1 `div` 8))
301+ <*> PR.dropWhile (<= (value * 2 `div` 8))
302+ <*> PR.dropWhile (<= (value * 3 `div` 8))
303+ <*> PR.dropWhile (<= (value * 4 `div` 8))
304+ <*> PR.dropWhile (<= (value * 5 `div` 8))
305+ <*> PR.dropWhile (<= (value * 6 `div` 8))
306+ <*> PR.dropWhile (<= (value * 7 `div` 8))
307+ <*> PR.dropWhile (<= value)
308+ )
309+
276310{-# INLINE splitApBefore #-}
277311splitApBefore :: Monad m
278312 => Int -> Stream m Int -> m (Either ParseError ())
@@ -291,10 +325,10 @@ splitApAfter value =
291325 <* PR.dropWhile (<= value)
292326 )
293327
294−{-# INLINE splitWith #-}
295−splitWith :: Monad m
328+{-# INLINE splitWith2 #-}
329+splitWith2 :: Monad m
296330 => Int -> Stream m Int -> m (Either ParseError ((), ()))
297−splitWith value =
331+splitWith2 value =
298332 Stream.parse
299333 (PR.splitWith (,)
300334 (PR.dropWhile (<= (value `div` 2)))
@@ -311,16 +345,91 @@ split_ value =
311345 (PR.dropWhile (<= value))
312346 )
313347
314−{-# INLINE alt #-}
315−alt :: Monad m
348+-- XXX dropWhile with applicative does not fuse
349+-- PR.dropWhile (<= (value * 1 `div` 4)) *> PR.die "alt"
350+{-# INLINE takeWhileFail #-}
351+takeWhileFail :: Monad m => (a -> Bool) -> Fold m a b -> Parser a m b
352+takeWhileFail predicate (Fold fstep finitial fextract) =
353+ Parser step initial extract
354+
355+ where
356+
357+ initial = do
358+ res <- finitial
359+ return $ case res of
360+ Fold.Partial s -> IPartial s
361+ Fold.Done b -> IDone b
362+
363+ step s a =
364+ if predicate a
365+ then do
366+ fres <- fstep s a
367+ return
368+ $ case fres of
369+ Fold.Partial s1 -> Partial 0 s1
370+ Fold.Done b -> Done 0 b
371+ else return $ Error "fail"
372+
373+ extract s = fmap (Done 0) (fextract s)
374+
375+{-# INLINE alt2 #-}
376+alt2 :: Monad m
316377 => Int -> Stream m Int -> m (Either ParseError ())
317−alt value =
378+alt2 value =
318379 Stream.parse
319380 (PR.alt
320− (PR.dropWhile (<= (value `div` 2)) *> PR.die "alt")
381+ (takeWhileFail (<= (value `div` 2)) Fold.drain)
321382 (PR.dropWhile (<= value))
322383 )
323384
385+{-# INLINE alt4 #-}
386+alt4 :: Monad m
387+ => Int -> Stream m Int -> m (Either ParseError ())
388+alt4 value =
389+ Stream.parse
390+ ( takeWhileFail (<= (value * 1 `div` 4)) Fold.drain
391+ <|> takeWhileFail (<= (value * 2 `div` 4)) Fold.drain
392+ <|> takeWhileFail (<= (value * 3 `div` 4)) Fold.drain
393+ <|> PR.dropWhile (<= value)
394+ )
395+
396+{-# INLINE alt8 #-}
397+alt8 :: Monad m
398+ => Int -> Stream m Int -> m (Either ParseError ())
399+alt8 value =
400+ Stream.parse
401+ ( takeWhileFail (<= (value * 1 `div` 8)) Fold.drain
402+ <|> takeWhileFail (<= (value * 2 `div` 8)) Fold.drain
403+ <|> takeWhileFail (<= (value * 3 `div` 8)) Fold.drain
404+ <|> takeWhileFail (<= (value * 4 `div` 8)) Fold.drain
405+ <|> takeWhileFail (<= (value * 5 `div` 8)) Fold.drain
406+ <|> takeWhileFail (<= (value * 6 `div` 8)) Fold.drain
407+ <|> takeWhileFail (<= (value * 7 `div` 8)) Fold.drain
408+ <|> PR.dropWhile (<= value)
409+ )
410+
411+{-# INLINE alt16 #-}
412+alt16 :: Monad m
413+ => Int -> Stream m Int -> m (Either ParseError ())
414+alt16 value =
415+ Stream.parse
416+ ( takeWhileFail (<= (value * 1 `div` 16)) Fold.drain
417+ <|> takeWhileFail (<= (value * 2 `div` 16)) Fold.drain
418+ <|> takeWhileFail (<= (value * 3 `div` 16)) Fold.drain
419+ <|> takeWhileFail (<= (value * 4 `div` 16)) Fold.drain
420+ <|> takeWhileFail (<= (value * 5 `div` 16)) Fold.drain
421+ <|> takeWhileFail (<= (value * 6 `div` 16)) Fold.drain
422+ <|> takeWhileFail (<= (value * 8 `div` 16)) Fold.drain
423+ <|> takeWhileFail (<= (value * 9 `div` 16)) Fold.drain
424+ <|> takeWhileFail (<= (value * 10 `div` 16)) Fold.drain
425+ <|> takeWhileFail (<= (value * 11 `div` 16)) Fold.drain
426+ <|> takeWhileFail (<= (value * 12 `div` 16)) Fold.drain
427+ <|> takeWhileFail (<= (value * 13 `div` 16)) Fold.drain
428+ <|> takeWhileFail (<= (value * 14 `div` 16)) Fold.drain
429+ <|> takeWhileFail (<= (value * 15 `div` 16)) Fold.drain
430+ <|> PR.dropWhile (<= value)
431+ )
432+
324433{-# INLINE altSmall #-}
325434altSmall :: Monad m
326435 => Int -> Stream m Int -> m ()
@@ -332,6 +441,61 @@ altSmall value =
332441 (PR.satisfy (<= value))
333442 )
334443
444+{-# INLINE monad #-}
445+monad :: Monad m
446+ => Int -> Stream m Int -> m (Either ParseError ())
447+monad value =
448+ Stream.parse
449+ $ do
450+ PR.dropWhile (<= (value `div` 2))
451+ PR.dropWhile (<= value)
452+
453+{-# INLINE monad4 #-}
454+monad4 :: Monad m
455+ => Int -> Stream m Int -> m (Either ParseError ())
456+monad4 value =
457+ Stream.parse $ do
458+ PR.dropWhile (<= (value `div` 4))
459+ PR.dropWhile (<= (value `div` 2))
460+ PR.dropWhile (<= (value * 3 `div` 4))
461+ PR.dropWhile (<= value)
462+
463+{-# INLINE monad8 #-}
464+monad8 :: Monad m
465+ => Int -> Stream m Int -> m (Either ParseError ())
466+monad8 value =
467+ Stream.parse $ do
468+ PR.dropWhile (<= (value * 1 `div` 8))
469+ PR.dropWhile (<= (value * 2 `div` 8))
470+ PR.dropWhile (<= (value * 3 `div` 8))
471+ PR.dropWhile (<= (value * 4 `div` 8))
472+ PR.dropWhile (<= (value * 5 `div` 8))
473+ PR.dropWhile (<= (value * 6 `div` 8))
474+ PR.dropWhile (<= (value * 7 `div` 8))
475+ PR.dropWhile (<= value)
476+
477+{-# INLINE monad16 #-}
478+monad16 :: Monad m
479+ => Int -> Stream m Int -> m (Either ParseError ())
480+monad16 value =
481+ Stream.parse $ do
482+ PR.dropWhile (<= (value * 1 `div` 16))
483+ PR.dropWhile (<= (value * 2 `div` 16))
484+ PR.dropWhile (<= (value * 3 `div` 16))
485+ PR.dropWhile (<= (value * 4 `div` 16))
486+ PR.dropWhile (<= (value * 5 `div` 16))
487+ PR.dropWhile (<= (value * 6 `div` 16))
488+ PR.dropWhile (<= (value * 7 `div` 16))
489+ PR.dropWhile (<= (value * 8 `div` 16))
490+ PR.dropWhile (<= (value * 9 `div` 16))
491+ PR.dropWhile (<= (value * 10 `div` 16))
492+ PR.dropWhile (<= (value * 11 `div` 16))
493+ PR.dropWhile (<= (value * 12 `div` 16))
494+ PR.dropWhile (<= (value * 13 `div` 16))
495+ PR.dropWhile (<= (value * 14 `div` 16))
496+ PR.dropWhile (<= (value * 15 `div` 16))
497+ PR.dropWhile (<= value)
498+
335499{-# INLINE takeEndBy_ #-}
336500takeEndBy_ :: Monad m
337501 => Int -> Stream m Int -> m (Either ParseError ())
@@ -379,6 +543,24 @@ longestAllAny value =
379543 )
380544-}
381545
546+-------------------------------------------------------------------------------
547+-- Spanning
548+-------------------------------------------------------------------------------
549+
550+{-# INLINE span #-}
551+span :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
552+span value = Stream.parse (PR.span (<= (value `div` 2)) Fold.drain Fold.drain)
553+
554+{-# INLINE spanBy #-}
555+spanBy :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
556+spanBy value =
557+ Stream.parse (PR.spanBy (\_ i -> i <= (value `div` 2)) Fold.drain Fold.drain)
558+
559+{-# INLINE spanByRolling #-}
560+spanByRolling :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
561+spanByRolling value =
562+ Stream.parse (PR.spanByRolling (\_ i -> i <= value `div` 2) Fold.drain Fold.drain)
563+
382564parseManyChunksOfSum :: Int -> Handle -> IO Int
383565parseManyChunksOfSum n inh =
384566 Stream.fold Fold.length
@@ -386,22 +568,6 @@ parseManyChunksOfSum n inh =
386568 (PR.fromFold $ Fold.take n Fold.sum)
387569 (Stream.unfold Handle.reader inh)
388570
389−-------------------------------------------------------------------------------
390−-- Parsing with unfolds
391−-------------------------------------------------------------------------------
392−
393−{-# INLINE parseManyUnfoldArrays #-}
394−parseManyUnfoldArrays :: Int -> [Array.Array Int] -> IO ()
395−parseManyUnfoldArrays count arrays = do
396− let src = Source.source (Just (Producer.OuterLoop arrays))
397− let parser = PR.fromFold (Fold.take count Fold.drain)
398− let readSrc =
399− Source.producer
400− $ Producer.concat Producer.fromList Array.producer
401− let streamParser =
402− Producer.simplify (Source.parseMany parser readSrc)
403− Stream.fold Fold.drain $ Stream.unfold streamParser src
404−
405571-------------------------------------------------------------------------------
406572-- Parsers in which -fspec-constr-recursive=16 is problematic
407573-------------------------------------------------------------------------------
@@ -415,6 +581,45 @@ lookAhead :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
415581lookAhead value =
416582 Stream.parse (PR.lookAhead (PR.takeWhile (<= value) Fold.drain) $> ())
417583
584+-- XXX The timing of this increased 3x after the stepify extract changes.
585+{-# INLINE sequenceA_ #-}
586+sequenceA_ :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
587+sequenceA_ value =
588+ Stream.parse (F.sequenceA_ $ replicate value (PR.satisfy (> 0)))
589+
590+-- quadratic complexity
591+{-# INLINE sequenceA #-}
592+sequenceA :: Monad m => Int -> Stream m Int -> m Int
593+sequenceA value xs = do
594+ x <- Stream.parse (TR.sequenceA (replicate value (PR.satisfy (> 0)))) xs
595+ return $ length x
596+
597+-- quadratic complexity
598+{-# INLINE sequence #-}
599+sequence :: Monad m => Int -> Stream m Int -> m Int
600+sequence value xs = do
601+ x <- Stream.parse (TR.sequence (replicate value (PR.satisfy (> 0)))) xs
602+ return $ length x
603+
604+{-# INLINE sequence_ #-}
605+sequence_ :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
606+sequence_ value xs =
607+ Stream.parse (foldr f (return ()) (replicate value (PR.takeBetween 0 1 Fold.drain))) xs
608+
609+ where
610+
611+ {-# INLINE f #-}
612+ f m k = m >>= (\_ -> k)
613+
614+-- choice using the "Alternative" instance with direct style parser type has
615+-- quadratic performance complexity.
616+--
617+{-# INLINE choiceAsum #-}
618+choiceAsum :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
619+choiceAsum value =
620+ Stream.parse (F.asum (replicate value (PR.satisfy (< 0)))
621+ AP.<|> PR.satisfy (> 0))
622+
418623{-
419624{-# INLINE choice #-}
420625choice :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
@@ -423,6 +628,22 @@ choice value =
423628 (PR.choice (replicate value (PR.satisfy (< 0))) AP.<|> PR.satisfy (> 0))
424629-}
425630
631+-------------------------------------------------------------------------------
632+-- Parsing with unfolds
633+-------------------------------------------------------------------------------
634+
635+{-# INLINE parseManyUnfoldArrays #-}
636+parseManyUnfoldArrays :: Int -> [Array.Array Int] -> IO ()
637+parseManyUnfoldArrays count arrays = do
638+ let src = Source.source (Just (Producer.OuterLoop arrays))
639+ let parser = PR.fromFold (Fold.take count Fold.drain)
640+ let readSrc =
641+ Source.producer
642+ $ Producer.concat Producer.fromList Array.producer
643+ let streamParser =
644+ Producer.simplify (Source.parseMany parser readSrc)
645+ Stream.fold Fold.drain $ Stream.unfold streamParser src
646+
426647-------------------------------------------------------------------------------
427648-- Stream transformation
428649-------------------------------------------------------------------------------
@@ -435,6 +656,35 @@ parseMany n =
435656 . Stream.catRights . Stream.parseMany (PR.fromFold $ Fold.take n Fold.mconcat)
436657 . fmap Sum
437658
659+{-# INLINE parseManyGroupBy #-}
660+parseManyGroupBy :: Monad m => (Int -> Int -> Bool) -> Stream m Int -> m ()
661+parseManyGroupBy cmp =
662+ Stream.fold Fold.drain . Stream.parseMany (PR.groupBy cmp Fold.drain)
663+
664+{-# INLINE parseManyGroupsRolling #-}
665+parseManyGroupsRolling :: Monad m => Bool -> Stream m Int -> m ()
666+parseManyGroupsRolling b =
667+ Stream.fold Fold.drain
668+ . Stream.parseMany (PR.groupByRolling (\_ _ -> b) Fold.drain)
669+
670+{-# INLINE parseManyGroupsRollingEither #-}
671+parseManyGroupsRollingEither :: Monad m =>
672+ (Int -> Int -> Bool) -> Int -> m ()
673+parseManyGroupsRollingEither cmp value = do
674+ sourceUnfoldrM value 1
675+ & Stream.parseMany (PR.groupByRollingEither cmp Fold.drain Fold.drain)
676+ & Stream.fold Fold.drain
677+
678+{-# INLINE parseManyGroupsRollingEitherAlt #-}
679+parseManyGroupsRollingEitherAlt :: Monad m =>
680+ (Int -> Int -> Bool) -> Int -> m ()
681+parseManyGroupsRollingEitherAlt cmp value = do
682+ sourceUnfoldrM value 1
683+ -- Make the input unsorted.
684+ & fmap (\x -> if even x then x + 2 else x)
685+ & Stream.parseMany (PR.groupByRollingEither cmp Fold.drain Fold.drain)
686+ & Stream.fold Fold.drain
687+
438688{-# INLINE parseIterate #-}
439689parseIterate :: Monad m => Int -> Stream m Int -> m ()
440690parseIterate n =
@@ -451,11 +701,6 @@ concatSequence :: Monad m => Stream m Int -> m (Either ParseError ())
451701concatSequence =
452702 Stream.parse $ PR.sequence (Stream.repeat PR.one) Fold.drain
453703
454−{-# INLINE parseManyGroupBy #-}
455−parseManyGroupBy :: Monad m => (Int -> Int -> Bool) -> Stream m Int -> m ()
456−parseManyGroupBy cmp =
457− Stream.fold Fold.drain . Stream.parseMany (PR.groupBy cmp Fold.drain)
458−
459704-------------------------------------------------------------------------------
460705-- Benchmarks
461706-------------------------------------------------------------------------------
@@ -477,6 +722,7 @@ o_1_space_serial value =
477722 , benchIOSink value "takeP" $ takeP value
478723 , benchIOSink value "dropWhile" $ dropWhile value
479724 , benchIOSink value "takeStartBy" $ takeStartBy value
725+ , benchIOSink value "takeEndBy_" $ takeEndBy_ value
480726 , benchIOSrc sourceEscapedFrames value "takeFramedByEsc_"
481727 $ takeFramedByEsc_ value
482728 , benchIOSink value "groupBy" $ groupBy
@@ -489,32 +735,70 @@ o_1_space_serial value =
489735 , benchIOSink value "deintercalate" $ deintercalate value
490736 , benchIOSink value "deintercalate1" $ deintercalate1 value
491737 , benchIOSink value "deintercalateAll" $ deintercalateAll value
492− , benchIOSink value "splitAp" $ splitAp value
738+ -- Applicative and Monad
739+ , benchIOSink value "splitAp2" $ splitAp2 value
740+ , benchIOSink value "splitAp4" $ splitAp4 value
741+ , benchIOSink value "splitAp8" $ splitAp8 value
493742 , benchIOSink value "splitApBefore" $ splitApBefore value
494743 , benchIOSink value "splitApAfter" $ splitApAfter value
495− , benchIOSink value "splitWith" $ splitWith value
496− , benchIOSink value "takeEndBy_" $ takeEndBy_ value
744+ , benchIOSink value "splitWith2" $ splitWith2 value
745+ , benchIOSink value "span" $ span value
746+ , benchIOSink value "spanBy" $ spanBy value
747+ , benchIOSink value "spanByRolling" $ spanByRolling value
748+ , benchIOSink value "monad2" $ monad value
749+ , benchIOSink value "monad4" $ monad4 value
750+ , benchIOSink value "monad8" $ monad8 value
751+ , benchIOSink value "monad16" $ monad16 value
752+ -- Alternative
753+ , benchIOSink value "alt2parseMany" $ altSmall value
754+ , benchIOSink value "alt2" $ alt2 value
755+ , benchIOSink value "alt4" $ alt4 value
756+ , benchIOSink value "alt8" $ alt8 value
757+ , benchIOSink value "alt16" $ alt16 value
497758 , benchIOSink value "many" many
498759 , benchIOSink value "many (wordBy even)" $ manyWordByEven
499760 , benchIOSink value "some" some
500761 , benchIOSink value "manyTill" $ manyTill value
762+ , benchIOSink value "parseMany" $ parseMany value
763+ , benchIOSink value "parseMany (take 1)" (parseMany 1)
764+ , benchIOSink value "parseMany (take all)" (parseMany value)
765+ , benchIOSink value "parseMany (groupBy (<))" (parseManyGroupBy (<))
766+ , benchIOSink value "parseMany (groupBy (==))" (parseManyGroupBy (==))
767+ , benchIOSink value "parseMany groupRollingBy (bound groups)"
768+ $ parseManyGroupsRolling False
769+ , benchIOSink value "parseMany groupRollingBy (1 group)"
770+ $ parseManyGroupsRolling True
771+ , bench "parseMany groupRollingByEither (Left)"
772+ $ nfIO $ parseManyGroupsRollingEitherLeft
773+ , bench "parseMany groupRollingByEither (Right)"
774+ $ nfIO $ parseManyGroupsRollingEitherRight
775+ , bench "parseMany groupRollingByEither (Alternating)"
776+ $ nfIO $ parseManyGroupsRollingEitherAlt1
777+ , benchIOSink value "parseIterate (take 1)" (parseIterate 1)
778+ , benchIOSink value "parseIterate (take all)" (parseIterate value)
779+ , benchIOSink value "concatSequence" concatSequence
501780 {-
502781 , benchIOSink value "tee" $ teeAllAny value
503782 , benchIOSink value "teeFst" $ teeFstAllAny value
504783 , benchIOSink value "shortest" $ shortestAllAny value
505784 , benchIOSink value "longest" $ longestAllAny value
506785 -}
507− , benchIOSink value "parseMany (take 1)" (parseMany 1)
508− , benchIOSink value "parseMany (take all)" (parseMany value)
509− , benchIOSink value "parseIterate (take 1)" (parseIterate 1)
510− , benchIOSink value "parseIterate (take all)" (parseIterate value)
511− , benchIOSink value "concatSequence" concatSequence
512− , benchIOSink value "parseMany (groupBy (<))" (parseManyGroupBy (<))
513− , benchIOSink value "parseMany (groupBy (==))" (parseManyGroupBy (==))
514786 , benchIOSink value "listEqBy" (listEqBy value)
515787 , benchIOSink value "streamEqBy" (streamEqBy value)
516788 ]
517789
790+ where
791+
792+ {-# NOINLINE parseManyGroupsRollingEitherLeft #-}
793+ parseManyGroupsRollingEitherLeft = parseManyGroupsRollingEither (<) value
794+
795+ {-# NOINLINE parseManyGroupsRollingEitherRight #-}
796+ parseManyGroupsRollingEitherRight = parseManyGroupsRollingEither (>) value
797+
798+ {-# NOINLINE parseManyGroupsRollingEitherAlt1 #-}
799+ parseManyGroupsRollingEitherAlt1 =
800+ parseManyGroupsRollingEitherAlt (>) value
801+
518802o_1_space_filesystem :: BenchEnv -> [Benchmark]
519803o_1_space_filesystem env =
520804 [ mkBench ("S.parseMany (Fold.take " ++ show (bigSize env) ++ " Fold.sum)") env
@@ -539,10 +823,6 @@ o_n_heap_serial value =
539823
540824 -- non-linear time complexity (parserD)
541825 , benchIOSink value "split_" $ split_ value
542− , benchIOSink value "altSmall (2 x parseMany)" $ altSmall value
543− , benchIOSink value "altBig (1/2 x 2)" $ alt value
544− -- XXX why O(n) heap?
545− -- , benchIOSink value "choice" $ choice value
546826
547827 -- These show non-linear time complexity.
548828 -- They accumulate the results in a list.
@@ -550,6 +830,17 @@ o_n_heap_serial value =
550830 , benchIOSink value "someAlt" someAlt
551831 ]
552832
833+-- accumulate results in a list in IO
834+o_n_space_serial :: Int -> [Benchmark]
835+o_n_space_serial value =
836+ [ benchIOSink value "sequenceA/100" $ sequenceA (value `div` 100)
837+ , benchIOSink value "sequenceA_/100" $ sequenceA_ (value `div` 100)
838+ , benchIOSink value "sequence/100" $ sequence (value `div` 100)
839+ , benchIOSink value "sequence_/100" $ sequence_ (value `div` 100)
840+ , benchIOSink value "choice (asum)/100" $ choiceAsum (value `div` 100)
841+ -- , benchIOSink value "choice/100" $ choice (value `div` 100)
842+ ]
843+
553844-------------------------------------------------------------------------------
554845-- Driver
555846-------------------------------------------------------------------------------
@@ -572,6 +863,7 @@ main = do
572863 , bgroup (o_1_space_prefix moduleName)
573864 (o_1_space_serial_unfold value arrays)
574865 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
866+ , bgroup (o_n_space_prefix moduleName) (o_n_space_serial value)
575867 ]
576868#else
577869 -- Enable FUSION_CHECK macro at the beginning of the file