@@ -22,19 +22,25 @@ module Main
25+import Control.Applicative ((<|>))
25import Control.DeepSeq (NFData(..))
26import Control.DeepSeq (NFData(..))
27+import Data.Function ((&))
26import Data.Functor (($>))
28import Data.Functor (($>))
27import Data.Monoid (Sum(..))
29import Data.Monoid (Sum(..))
28import GHC.Magic (inline)
30import GHC.Magic (inline)
29import GHC.Magic (noinline)
31import GHC.Magic (noinline)
30import System.IO (Handle)
32import System.IO (Handle)
31import System.Random (randomRIO)
33import 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(..))
33import Streamly.Internal.Data.Stream.StreamD (Stream)
37import Streamly.Internal.Data.Stream.StreamD (Stream)
34import Prelude hiding
38import Prelude hiding
35− (any, all, take, sequence, sequence_, sequenceA, takeWhile, dropWhile)
39+ (any, all, take, sequence, sequence_, sequenceA, takeWhile, dropWhile, span)
37import qualified Control.Applicative as AP
41import qualified Control.Applicative as AP
42+import qualified Data.Foldable as F
43+import qualified Data.Traversable as TR
38import qualified Streamly.FileSystem.Handle as Handle
44import qualified Streamly.FileSystem.Handle as Handle
39import qualified Streamly.Internal.Data.Array as Array
45import qualified Streamly.Internal.Data.Array as Array
40import qualified Streamly.Internal.Data.Fold as Fold
46import qualified Streamly.Internal.Data.Fold as Fold
@@ -263,16 +269,44 @@ manyTill :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
263manyTill value =
269manyTill value =
264 Stream.parse (PR.manyTill (PR.satisfy (> 0)) (PR.satisfy (== value)) Fold.length)
270 Stream.parse (PR.manyTill (PR.satisfy (> 0)) (PR.satisfy (== value)) Fold.length)
266−{-# INLINE splitAp #-}
272+{-# INLINE splitAp2 #-}
267−splitAp :: Monad m
273+splitAp2 :: Monad m
268 => Int -> Stream m Int -> m (Either ParseError ((), ()))
274 => Int -> Stream m Int -> m (Either ParseError ((), ()))
269−splitAp value =
275+splitAp2 value =
270 Stream.parse
276 Stream.parse
272 <$> PR.dropWhile (<= (value `div` 2))
278 <$> PR.dropWhile (<= (value `div` 2))
273 <*> PR.dropWhile (<= value)
279 <*> PR.dropWhile (<= value)
282+{-# INLINE splitAp4 #-}
284+ => Int -> Stream m Int -> m (Either ParseError ())
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)
294+{-# INLINE splitAp8 #-}
296+ => Int -> Stream m Int -> m (Either ParseError ())
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)
276{-# INLINE splitApBefore #-}
310{-# INLINE splitApBefore #-}
277splitApBefore :: Monad m
311splitApBefore :: Monad m
278 => Int -> Stream m Int -> m (Either ParseError ())
312 => Int -> Stream m Int -> m (Either ParseError ())
@@ -291,10 +325,10 @@ splitApAfter value =
291 <* PR.dropWhile (<= value)
325 <* PR.dropWhile (<= value)
294−{-# INLINE splitWith #-}
328+{-# INLINE splitWith2 #-}
295−splitWith :: Monad m
329+splitWith2 :: Monad m
296 => Int -> Stream m Int -> m (Either ParseError ((), ()))
330 => Int -> Stream m Int -> m (Either ParseError ((), ()))
297−splitWith value =
331+splitWith2 value =
298 Stream.parse
332 Stream.parse
299 (PR.splitWith (,)
333 (PR.splitWith (,)
300 (PR.dropWhile (<= (value `div` 2)))
334 (PR.dropWhile (<= (value `div` 2)))
@@ -311,16 +345,91 @@ split_ value =
311 (PR.dropWhile (<= value))
345 (PR.dropWhile (<= value))
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
359+ return $ case res of
360+ Fold.Partial s -> IPartial s
361+ Fold.Done b -> IDone b
369+ Fold.Partial s1 -> Partial 0 s1
370+ Fold.Done b -> Done 0 b
371+ else return $ Error "fail"
373+ extract s = fmap (Done 0) (fextract s)
314−{-# INLINE alt #-}
375+{-# INLINE alt2 #-}
315−alt :: Monad m
376+alt2 :: Monad m
316 => Int -> Stream m Int -> m (Either ParseError ())
377 => Int -> Stream m Int -> m (Either ParseError ())
317−alt value =
378+alt2 value =
318 Stream.parse
379 Stream.parse
320− (PR.dropWhile (<= (value `div` 2)) *> PR.die "alt")
381+ (takeWhileFail (<= (value `div` 2)) Fold.drain)
321 (PR.dropWhile (<= value))
382 (PR.dropWhile (<= value))
387+ => Int -> Stream m Int -> m (Either ParseError ())
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)
398+ => Int -> Stream m Int -> m (Either ParseError ())
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)
413+ => Int -> Stream m Int -> m (Either ParseError ())
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)
324{-# INLINE altSmall #-}
433{-# INLINE altSmall #-}
325altSmall :: Monad m
434altSmall :: Monad m
326 => Int -> Stream m Int -> m ()
435 => Int -> Stream m Int -> m ()
@@ -332,6 +441,61 @@ altSmall value =
332 (PR.satisfy (<= value))
441 (PR.satisfy (<= value))
446+ => Int -> Stream m Int -> m (Either ParseError ())
450+ PR.dropWhile (<= (value `div` 2))
451+ PR.dropWhile (<= value)
453+{-# INLINE monad4 #-}
455+ => Int -> Stream m Int -> m (Either ParseError ())
458+ PR.dropWhile (<= (value `div` 4))
459+ PR.dropWhile (<= (value `div` 2))
460+ PR.dropWhile (<= (value * 3 `div` 4))
461+ PR.dropWhile (<= value)
463+{-# INLINE monad8 #-}
465+ => Int -> Stream m Int -> m (Either ParseError ())
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)
477+{-# INLINE monad16 #-}
479+ => Int -> Stream m Int -> m (Either ParseError ())
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)
335{-# INLINE takeEndBy_ #-}
499{-# INLINE takeEndBy_ #-}
336takeEndBy_ :: Monad m
500takeEndBy_ :: Monad m
337 => Int -> Stream m Int -> m (Either ParseError ())
501 => Int -> Stream m Int -> m (Either ParseError ())
@@ -379,6 +543,24 @@ longestAllAny value =
546+-------------------------------------------------------------------------------
548+-------------------------------------------------------------------------------
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)
554+{-# INLINE spanBy #-}
555+spanBy :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
557+ Stream.parse (PR.spanBy (\_ i -> i <= (value `div` 2)) Fold.drain Fold.drain)
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)
382parseManyChunksOfSum :: Int -> Handle -> IO Int
564parseManyChunksOfSum :: Int -> Handle -> IO Int
383parseManyChunksOfSum n inh =
565parseManyChunksOfSum n inh =
384 Stream.fold Fold.length
566 Stream.fold Fold.length
@@ -386,22 +568,6 @@ parseManyChunksOfSum n inh =
386 (PR.fromFold $ Fold.take n Fold.sum)
568 (PR.fromFold $ Fold.take n Fold.sum)
387 (Stream.unfold Handle.reader inh)
569 (Stream.unfold Handle.reader inh)
389−-------------------------------------------------------------------------------
390−-- Parsing with unfolds
391−-------------------------------------------------------------------------------
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)
400− $ Producer.concat Producer.fromList Array.producer
402− Producer.simplify (Source.parseMany parser readSrc)
403− Stream.fold Fold.drain $ Stream.unfold streamParser src
405-------------------------------------------------------------------------------
571-------------------------------------------------------------------------------
406-- Parsers in which -fspec-constr-recursive=16 is problematic
572-- Parsers in which -fspec-constr-recursive=16 is problematic
407-------------------------------------------------------------------------------
573-------------------------------------------------------------------------------
@@ -415,6 +581,45 @@ lookAhead :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
415lookAhead value =
581lookAhead value =
416 Stream.parse (PR.lookAhead (PR.takeWhile (<= value) Fold.drain) $> ())
582 Stream.parse (PR.lookAhead (PR.takeWhile (<= value) Fold.drain) $> ())
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 ())
588+ Stream.parse (F.sequenceA_ $ replicate value (PR.satisfy (> 0)))
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
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
604+{-# INLINE sequence_ #-}
605+sequence_ :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
607+ Stream.parse (foldr f (return ()) (replicate value (PR.takeBetween 0 1 Fold.drain))) xs
612+ f m k = m >>= (\_ -> k)
614+-- choice using the "Alternative" instance with direct style parser type has
615+-- quadratic performance complexity.
617+{-# INLINE choiceAsum #-}
618+choiceAsum :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
620+ Stream.parse (F.asum (replicate value (PR.satisfy (< 0)))
621+ AP.<|> PR.satisfy (> 0))
419{-# INLINE choice #-}
624{-# INLINE choice #-}
420choice :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
625choice :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
@@ -423,6 +628,22 @@ choice value =
423 (PR.choice (replicate value (PR.satisfy (< 0))) AP.<|> PR.satisfy (> 0))
628 (PR.choice (replicate value (PR.satisfy (< 0))) AP.<|> PR.satisfy (> 0))
631+-------------------------------------------------------------------------------
632+-- Parsing with unfolds
633+-------------------------------------------------------------------------------
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)
642+ $ Producer.concat Producer.fromList Array.producer
644+ Producer.simplify (Source.parseMany parser readSrc)
645+ Stream.fold Fold.drain $ Stream.unfold streamParser src
426-------------------------------------------------------------------------------
647-------------------------------------------------------------------------------
427-- Stream transformation
648-- Stream transformation
428-------------------------------------------------------------------------------
649-------------------------------------------------------------------------------
@@ -435,6 +656,35 @@ parseMany n =
435 . Stream.catRights . Stream.parseMany (PR.fromFold $ Fold.take n Fold.mconcat)
656 . Stream.catRights . Stream.parseMany (PR.fromFold $ Fold.take n Fold.mconcat)
436 . fmap Sum
657 . fmap Sum
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)
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)
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
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
438{-# INLINE parseIterate #-}
688{-# INLINE parseIterate #-}
439parseIterate :: Monad m => Int -> Stream m Int -> m ()
689parseIterate :: Monad m => Int -> Stream m Int -> m ()
440parseIterate n =
690parseIterate n =
@@ -451,11 +701,6 @@ concatSequence :: Monad m => Stream m Int -> m (Either ParseError ())
451concatSequence =
701concatSequence =
452 Stream.parse $ PR.sequence (Stream.repeat PR.one) Fold.drain
702 Stream.parse $ PR.sequence (Stream.repeat PR.one) Fold.drain
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)
459-------------------------------------------------------------------------------
704-------------------------------------------------------------------------------
460-- Benchmarks
705-- Benchmarks
461-------------------------------------------------------------------------------
706-------------------------------------------------------------------------------
@@ -477,6 +722,7 @@ o_1_space_serial value =
477 , benchIOSink value "takeP" $ takeP value
722 , benchIOSink value "takeP" $ takeP value
478 , benchIOSink value "dropWhile" $ dropWhile value
723 , benchIOSink value "dropWhile" $ dropWhile value
479 , benchIOSink value "takeStartBy" $ takeStartBy value
724 , benchIOSink value "takeStartBy" $ takeStartBy value
725+ , benchIOSink value "takeEndBy_" $ takeEndBy_ value
480 , benchIOSrc sourceEscapedFrames value "takeFramedByEsc_"
726 , benchIOSrc sourceEscapedFrames value "takeFramedByEsc_"
481 $ takeFramedByEsc_ value
727 $ takeFramedByEsc_ value
482 , benchIOSink value "groupBy" $ groupBy
728 , benchIOSink value "groupBy" $ groupBy
@@ -489,32 +735,70 @@ o_1_space_serial value =
489 , benchIOSink value "deintercalate" $ deintercalate value
735 , benchIOSink value "deintercalate" $ deintercalate value
490 , benchIOSink value "deintercalate1" $ deintercalate1 value
736 , benchIOSink value "deintercalate1" $ deintercalate1 value
491 , benchIOSink value "deintercalateAll" $ deintercalateAll value
737 , benchIOSink value "deintercalateAll" $ deintercalateAll value
738+ -- Applicative and Monad
492− , benchIOSink value "splitAp" $ splitAp value
739+ , benchIOSink value "splitAp2" $ splitAp2 value
740+ , benchIOSink value "splitAp4" $ splitAp4 value
741+ , benchIOSink value "splitAp8" $ splitAp8 value
493 , benchIOSink value "splitApBefore" $ splitApBefore value
742 , benchIOSink value "splitApBefore" $ splitApBefore value
494 , benchIOSink value "splitApAfter" $ splitApAfter value
743 , benchIOSink value "splitApAfter" $ splitApAfter value
495− , benchIOSink value "splitWith" $ splitWith 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
753+ , benchIOSink value "alt2parseMany" $ altSmall value
754+ , benchIOSink value "alt2" $ alt2 value
755+ , benchIOSink value "alt4" $ alt4 value
496− , benchIOSink value "takeEndBy_" $ takeEndBy_ value
756+ , benchIOSink value "alt8" $ alt8 value
757+ , benchIOSink value "alt16" $ alt16 value
497 , benchIOSink value "many" many
758 , benchIOSink value "many" many
498 , benchIOSink value "many (wordBy even)" $ manyWordByEven
759 , benchIOSink value "many (wordBy even)" $ manyWordByEven
499 , benchIOSink value "some" some
760 , benchIOSink value "some" some
500 , benchIOSink value "manyTill" $ manyTill value
761 , 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
502 , benchIOSink value "tee" $ teeAllAny value
781 , benchIOSink value "tee" $ teeAllAny value
503 , benchIOSink value "teeFst" $ teeFstAllAny value
782 , benchIOSink value "teeFst" $ teeFstAllAny value
504 , benchIOSink value "shortest" $ shortestAllAny value
783 , benchIOSink value "shortest" $ shortestAllAny value
505 , benchIOSink value "longest" $ longestAllAny value
784 , benchIOSink value "longest" $ longestAllAny value
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 (==))
514 , benchIOSink value "listEqBy" (listEqBy value)
786 , benchIOSink value "listEqBy" (listEqBy value)
515 , benchIOSink value "streamEqBy" (streamEqBy value)
787 , benchIOSink value "streamEqBy" (streamEqBy value)
792+ {-# NOINLINE parseManyGroupsRollingEitherLeft #-}
793+ parseManyGroupsRollingEitherLeft = parseManyGroupsRollingEither (<) value
795+ {-# NOINLINE parseManyGroupsRollingEitherRight #-}
796+ parseManyGroupsRollingEitherRight = parseManyGroupsRollingEither (>) value
798+ {-# NOINLINE parseManyGroupsRollingEitherAlt1 #-}
799+ parseManyGroupsRollingEitherAlt1 =
800+ parseManyGroupsRollingEitherAlt (>) value
518o_1_space_filesystem :: BenchEnv -> [Benchmark]
802o_1_space_filesystem :: BenchEnv -> [Benchmark]
519o_1_space_filesystem env =
803o_1_space_filesystem env =
520 [ mkBench ("S.parseMany (Fold.take " ++ show (bigSize env) ++ " Fold.sum)") env
804 [ mkBench ("S.parseMany (Fold.take " ++ show (bigSize env) ++ " Fold.sum)") env
@@ -539,10 +823,6 @@ o_n_heap_serial value =
540 -- non-linear time complexity (parserD)
824 -- non-linear time complexity (parserD)
541 , benchIOSink value "split_" $ split_ value
825 , 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
547 -- These show non-linear time complexity.
827 -- These show non-linear time complexity.
548 -- They accumulate the results in a list.
828 -- They accumulate the results in a list.
@@ -550,6 +830,17 @@ o_n_heap_serial value =
550 , benchIOSink value "someAlt" someAlt
830 , benchIOSink value "someAlt" someAlt
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)
553-------------------------------------------------------------------------------
844-------------------------------------------------------------------------------
555-------------------------------------------------------------------------------
846-------------------------------------------------------------------------------
@@ -572,6 +863,7 @@ main = do
572 , bgroup (o_1_space_prefix moduleName)
863 , bgroup (o_1_space_prefix moduleName)
573 (o_1_space_serial_unfold value arrays)
864 (o_1_space_serial_unfold value arrays)
574 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
865 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
866+ , bgroup (o_n_space_prefix moduleName) (o_n_space_serial value)
577 -- Enable FUSION_CHECK macro at the beginning of the file
869 -- Enable FUSION_CHECK macro at the beginning of the file