1{-# OPTIONS_GHC -Wno-deprecations #-}
5{-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dsuppress-all #-}
9-- Module : Streamly.Benchmark.Data.Parser
10-- Copyright : (c) 2020 Composewell Technologies
12-- License : BSD-3-Clause
13-- Maintainer : streamly@composewell.com
16{-# LANGUAGE FlexibleContexts #-}
17{-# LANGUAGE ScopedTypeVariables #-}
18{-# OPTIONS_GHC -Wno-orphans #-}
25import Control.Applicative ((<|>))
26import Control.DeepSeq (NFData(..))
27import Data.Function ((&))
28import Data.Functor (($>))
29import Data.Monoid (Sum(..))
30import GHC.Magic (inline)
31import GHC.Magic (noinline)
32import System.IO (Handle)
33import System.Random (randomRIO)
34import Streamly.Internal.Data.Fold (Fold(..))
35import Streamly.Internal.Data.Parser
36 (ParseError(..), Parser(..), Initial(..), Step(..))
37import Streamly.Internal.Data.Stream (Stream)
39 (any, all, take, sequence, sequence_, sequenceA, takeWhile, dropWhile, span)
41import qualified Control.Applicative as AP
42import qualified Data.Foldable as F
43import qualified Data.Traversable as TR
44import qualified Streamly.FileSystem.Handle as Handle
45import qualified Streamly.Internal.Data.Array as Array
46import qualified Streamly.Internal.Data.Fold as Fold
47import qualified Streamly.Internal.Data.Parser as PR
48import qualified Streamly.Data.Stream as Stream
49import qualified Streamly.Internal.Data.Producer as Producer
50import qualified Streamly.Internal.Data.Stream as Stream
52import Gauge hiding (env)
53import Streamly.Benchmark.Common
54import Streamly.Benchmark.Common.Handle
56-------------------------------------------------------------------------------
58-------------------------------------------------------------------------------
60-- XXX these can be moved to the common module
62{-# INLINE sourceUnfoldrM #-}
63sourceUnfoldrM :: Monad m => Int -> Int -> Stream m Int
64sourceUnfoldrM value n = Stream.unfoldrM step n
69 else return (Just (cnt, cnt + 1))
71-- | Generates something like this: { { \{ \{ } }. The stream consists of
72-- three parts, the first part is contains a sequence of `{`. The second part
73-- contains a sequence pf escaped values `\{`. The third part contains a
75{-# INLINE sourceEscapedFrames #-}
81sourceEscapedFrames value n = Stream.unfoldrM step n
87 value1 = value `div` 4
90 | cnt > 4 * value1 = return Nothing
91 | cnt <= value1 = return $ Just (cbOpen, cnt + 1)
92 | cnt > 3 * value1 = return $ Just (cbClose, cnt + 1)
96 $ if (cnt - value1) `mod` 2 == 1
98 else (cbOpen, cnt + 1)
100{-# INLINE benchIOSrc #-}
103 => (Int -> Int -> Stream IO a)
106 -> (Stream IO a -> IO b)
108benchIOSrc src value name f =
109 bench name $ nfIO $ randomRIO (1,1) >>= f . src value
111-- | Takes a fold method, and uses it with a default source.
112{-# INLINE benchIOSink #-}
115 => Int -> String -> (Stream IO Int -> IO b) -> Benchmark
116benchIOSink value name f =
117 bench name $ nfIO $ randomRIO (1,1) >>= f . sourceUnfoldrM value
119-------------------------------------------------------------------------------
121-------------------------------------------------------------------------------
123{-# INLINE takeBetween #-}
124takeBetween :: Monad m => Int -> Stream m a -> m (Either ParseError ())
125takeBetween value = Stream.parse (PR.takeBetween 0 value Fold.drain)
128takeEQ :: Monad m => Int -> Stream m a -> m (Either ParseError ())
129takeEQ value = Stream.parse (PR.takeEQ value Fold.drain)
132takeGE :: Monad m => Int -> Stream m a -> m (Either ParseError ())
133takeGE value = Stream.parse (PR.takeGE value Fold.drain)
135{-# INLINE dropWhile #-}
136dropWhile :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
137dropWhile value = Stream.parse (PR.dropWhile (<= value))
139{-# INLINE takeStartBy #-}
140takeStartBy :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
141takeStartBy value stream = do
142 let stream2 = value `Stream.cons` stream
143 Stream.parse (PR.takeStartBy (== value) Fold.drain) stream2
145takeFramedByEsc_ :: Monad m => Int -> Stream m Char -> m (Either ParseError ())
146takeFramedByEsc_ _ = Stream.parse parser
154 parser = PR.takeFramedByEsc_ isEsc isBegin isEnd Fold.drain
156{-# INLINE listEqBy #-}
157listEqBy :: Int -> Stream IO Int -> IO (Either ParseError [Int])
158listEqBy len = Stream.parse (PR.listEqBy (==) [1 .. len])
160{-# INLINE streamEqBy #-}
161streamEqBy :: Int -> Stream IO Int -> IO (Either ParseError ())
162streamEqBy len = Stream.parse (PR.streamEqBy (==) (Stream.enumerateFromTo 1 len))
164{-# INLINE takeWhile #-}
165takeWhile :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
166takeWhile value = Stream.parse (PR.takeWhile (<= value) Fold.drain)
168takeWhileP :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
170 Stream.parse (PR.takeWhileP (<= value) (PR.takeWhile (<= value - 1) Fold.drain))
173takeP :: Monad m => Int -> Stream m a -> m (Either ParseError ())
174takeP value = Stream.parse (PR.takeP value (PR.fromFold Fold.drain))
176{-# INLINE groupBy #-}
177groupBy :: Monad m => Stream m Int -> m (Either ParseError ())
178groupBy = Stream.parse (PR.groupBy (<=) Fold.drain)
180{-# INLINE groupByRolling #-}
181groupByRolling :: Monad m => Stream m Int -> m (Either ParseError ())
182groupByRolling = Stream.parse (PR.groupByRolling (<=) Fold.drain)
185wordBy :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
186wordBy value = Stream.parse (PR.wordBy (>= value) Fold.drain)
188{-# INLINE sepByWords #-}
189sepByWords :: Monad m => Stream m Int -> m (Either ParseError ())
190sepByWords = Stream.parse (wrds even Fold.drain)
192 wrds p = PR.sepBy (PR.takeWhile (not . p) Fold.drain) (PR.dropWhile p)
194{-# INLINE sepByAllWords #-}
195sepByAllWords :: Monad m => Stream m Int -> m (Either ParseError ())
196sepByAllWords = Stream.parse (wrds even Fold.drain)
198 wrds p = PR.sepByAll (PR.takeWhile (not . p) Fold.drain) (PR.dropWhile p)
200-- Returning a list to compare with the sepBy1 in ParserK
202sepBy1 :: Monad m => Stream m Int -> m (Either ParseError [Int])
204 Stream.parse (PR.sepBy1 (PR.satisfy odd) (PR.satisfy even) Fold.toList) xs
206{-# INLINE sepByWords1 #-}
207sepByWords1 :: Monad m => Stream m Int -> m (Either ParseError ())
208sepByWords1 = Stream.parse (wrds even Fold.drain)
210 wrds p = PR.sepBy1 (PR.takeWhile (not . p) Fold.drain) (PR.dropWhile p)
212{-# INLINE deintercalate #-}
213deintercalate :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
214deintercalate _ = Stream.parse (partition even)
220 (PR.takeWhile (not . p) Fold.sum) (PR.takeWhile p Fold.sum) Fold.drain
222{-# INLINE deintercalate1 #-}
223deintercalate1 :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
224deintercalate1 _ = Stream.parse (partition even)
230 (PR.takeWhile (not . p) Fold.sum) (PR.takeWhile p Fold.sum) Fold.drain
232{-# INLINE deintercalateAll #-}
233deintercalateAll :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
234deintercalateAll _ = Stream.parse (partition even)
240 (PR.takeWhile (not . p) Fold.sum) (PR.takeWhile p Fold.sum) Fold.drain
242{-# INLINE manyWordByEven #-}
243manyWordByEven :: Monad m => Stream m Int -> m (Either ParseError ())
244manyWordByEven = Stream.parse (PR.many (PR.wordBy even Fold.drain) Fold.drain)
247many :: Monad m => Stream m Int -> m (Either ParseError Int)
248many = Stream.parse (PR.many (PR.satisfy (> 0)) Fold.length)
250{-# INLINE manyAlt #-}
251manyAlt :: Monad m => Stream m Int -> m Int
253 x <- Stream.parse (AP.many (PR.satisfy (> 0))) xs
254 return $ Prelude.length x
257some :: Monad m => Stream m Int -> m (Either ParseError Int)
258some = Stream.parse (PR.some (PR.satisfy (> 0)) Fold.length)
260{-# INLINE someAlt #-}
261someAlt :: Monad m => Stream m Int -> m Int
263 x <- Stream.parse (AP.some (PR.satisfy (> 0))) xs
264 return $ Prelude.length x
266{-# INLINE manyTill #-}
267manyTill :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
269 Stream.parse (PR.manyTill (PR.satisfy (> 0)) (PR.satisfy (== value)) Fold.length)
271{-# INLINE splitAp2 #-}
273 => Int -> Stream m Int -> m (Either ParseError ((), ()))
277 <$> PR.dropWhile (<= (value `div` 2))
278 <*> PR.dropWhile (<= value)
281{-# INLINE splitAp4 #-}
283 => Int -> Stream m Int -> m (Either ParseError ())
286 ( (\() () () () -> ())
287 <$> PR.dropWhile (<= (value * 1 `div` 4))
288 <*> PR.dropWhile (<= (value * 2 `div` 4))
289 <*> PR.dropWhile (<= (value * 3 `div` 4))
290 <*> PR.dropWhile (<= value)
293{-# INLINE splitAp8 #-}
295 => Int -> Stream m Int -> m (Either ParseError ())
298 ( (\() () () () () () () () -> ())
299 <$> PR.dropWhile (<= (value * 1 `div` 8))
300 <*> PR.dropWhile (<= (value * 2 `div` 8))
301 <*> PR.dropWhile (<= (value * 3 `div` 8))
302 <*> PR.dropWhile (<= (value * 4 `div` 8))
303 <*> PR.dropWhile (<= (value * 5 `div` 8))
304 <*> PR.dropWhile (<= (value * 6 `div` 8))
305 <*> PR.dropWhile (<= (value * 7 `div` 8))
306 <*> PR.dropWhile (<= value)
309{-# INLINE splitApBefore #-}
310splitApBefore :: Monad m
311 => Int -> Stream m Int -> m (Either ParseError ())
314 ( PR.dropWhile (<= (value `div` 2))
315 *> PR.dropWhile (<= value)
318{-# INLINE splitApAfter #-}
319splitApAfter :: Monad m
320 => Int -> Stream m Int -> m (Either ParseError ())
323 ( PR.dropWhile (<= (value `div` 2))
324 <* PR.dropWhile (<= value)
327{-# INLINE splitWith2 #-}
329 => Int -> Stream m Int -> m (Either ParseError ((), ()))
333 (PR.dropWhile (<= (value `div` 2)))
334 (PR.dropWhile (<= value))
339 => Int -> Stream m Int -> m (Either ParseError ())
343 (PR.dropWhile (<= (value `div` 2)))
344 (PR.dropWhile (<= value))
347-- XXX dropWhile with applicative does not fuse
348-- PR.dropWhile (<= (value * 1 `div` 4)) *> PR.die "alt"
349{-# INLINE takeWhileFail #-}
350takeWhileFail :: Monad m => (a -> Bool) -> Fold m a b -> Parser a m b
351takeWhileFail predicate (Fold fstep finitial fextract) =
352 Parser step initial extract
359 Fold.Partial s -> IPartial s
360 Fold.Done b -> IDone b
368 Fold.Partial s1 -> Partial 0 s1
369 Fold.Done b -> Done 0 b
370 else return $ Error "fail"
372 extract s = fmap (Done 0) (fextract s)
376 => Int -> Stream m Int -> m (Either ParseError ())
380 (takeWhileFail (<= (value `div` 2)) Fold.drain)
381 (PR.dropWhile (<= value))
386 => Int -> Stream m Int -> m (Either ParseError ())
389 ( takeWhileFail (<= (value * 1 `div` 4)) Fold.drain
390 <|> takeWhileFail (<= (value * 2 `div` 4)) Fold.drain
391 <|> takeWhileFail (<= (value * 3 `div` 4)) Fold.drain
392 <|> PR.dropWhile (<= value)
397 => Int -> Stream m Int -> m (Either ParseError ())
400 ( takeWhileFail (<= (value * 1 `div` 8)) Fold.drain
401 <|> takeWhileFail (<= (value * 2 `div` 8)) Fold.drain
402 <|> takeWhileFail (<= (value * 3 `div` 8)) Fold.drain
403 <|> takeWhileFail (<= (value * 4 `div` 8)) Fold.drain
404 <|> takeWhileFail (<= (value * 5 `div` 8)) Fold.drain
405 <|> takeWhileFail (<= (value * 6 `div` 8)) Fold.drain
406 <|> takeWhileFail (<= (value * 7 `div` 8)) Fold.drain
407 <|> PR.dropWhile (<= value)
412 => Int -> Stream m Int -> m (Either ParseError ())
415 ( takeWhileFail (<= (value * 1 `div` 16)) Fold.drain
416 <|> takeWhileFail (<= (value * 2 `div` 16)) Fold.drain
417 <|> takeWhileFail (<= (value * 3 `div` 16)) Fold.drain
418 <|> takeWhileFail (<= (value * 4 `div` 16)) Fold.drain
419 <|> takeWhileFail (<= (value * 5 `div` 16)) Fold.drain
420 <|> takeWhileFail (<= (value * 6 `div` 16)) Fold.drain
421 <|> takeWhileFail (<= (value * 8 `div` 16)) Fold.drain
422 <|> takeWhileFail (<= (value * 9 `div` 16)) Fold.drain
423 <|> takeWhileFail (<= (value * 10 `div` 16)) Fold.drain
424 <|> takeWhileFail (<= (value * 11 `div` 16)) Fold.drain
425 <|> takeWhileFail (<= (value * 12 `div` 16)) Fold.drain
426 <|> takeWhileFail (<= (value * 13 `div` 16)) Fold.drain
427 <|> takeWhileFail (<= (value * 14 `div` 16)) Fold.drain
428 <|> takeWhileFail (<= (value * 15 `div` 16)) Fold.drain
429 <|> PR.dropWhile (<= value)
432{-# INLINE altSmall #-}
434 => Int -> Stream m Int -> m ()
436 Stream.fold Fold.drain .
439 (PR.satisfy (>= value) *> PR.die "alt")
440 (PR.satisfy (<= value))
445 => Int -> Stream m Int -> m (Either ParseError ())
449 PR.dropWhile (<= (value `div` 2))
450 PR.dropWhile (<= value)
454 => Int -> Stream m Int -> m (Either ParseError ())
457 PR.dropWhile (<= (value `div` 4))
458 PR.dropWhile (<= (value `div` 2))
459 PR.dropWhile (<= (value * 3 `div` 4))
460 PR.dropWhile (<= value)
464 => Int -> Stream m Int -> m (Either ParseError ())
467 PR.dropWhile (<= (value * 1 `div` 8))
468 PR.dropWhile (<= (value * 2 `div` 8))
469 PR.dropWhile (<= (value * 3 `div` 8))
470 PR.dropWhile (<= (value * 4 `div` 8))
471 PR.dropWhile (<= (value * 5 `div` 8))
472 PR.dropWhile (<= (value * 6 `div` 8))
473 PR.dropWhile (<= (value * 7 `div` 8))
474 PR.dropWhile (<= value)
476{-# INLINE monad16 #-}
478 => Int -> Stream m Int -> m (Either ParseError ())
481 PR.dropWhile (<= (value * 1 `div` 16))
482 PR.dropWhile (<= (value * 2 `div` 16))
483 PR.dropWhile (<= (value * 3 `div` 16))
484 PR.dropWhile (<= (value * 4 `div` 16))
485 PR.dropWhile (<= (value * 5 `div` 16))
486 PR.dropWhile (<= (value * 6 `div` 16))
487 PR.dropWhile (<= (value * 7 `div` 16))
488 PR.dropWhile (<= (value * 8 `div` 16))
489 PR.dropWhile (<= (value * 9 `div` 16))
490 PR.dropWhile (<= (value * 10 `div` 16))
491 PR.dropWhile (<= (value * 11 `div` 16))
492 PR.dropWhile (<= (value * 12 `div` 16))
493 PR.dropWhile (<= (value * 13 `div` 16))
494 PR.dropWhile (<= (value * 14 `div` 16))
495 PR.dropWhile (<= (value * 15 `div` 16))
496 PR.dropWhile (<= value)
498{-# INLINE takeEndBy_ #-}
500 => Int -> Stream m Int -> m (Either ParseError ())
501takeEndBy_ value = Stream.parse (PR.takeEndBy_ (>= value) (PR.fromFold Fold.drain))
504{-# INLINE teeAllAny #-}
506 => Int -> Stream m Int -> m ((), ())
510 (PR.dropWhile (<= value))
511 (PR.dropWhile (<= value))
514{-# INLINE teeFstAllAny #-}
515teeFstAllAny :: Monad m
516 => Int -> Stream m Int -> m ((), ())
520 (PR.dropWhile (<= value))
521 (PR.dropWhile (<= value))
524{-# INLINE shortestAllAny #-}
525shortestAllAny :: Monad m
526 => Int -> Stream m Int -> m (Either ParseError ())
527shortestAllAny value =
530 (PR.dropWhile (<= value))
531 (PR.dropWhile (<= value))
534{-# INLINE longestAllAny #-}
535longestAllAny :: Monad m
536 => Int -> Stream m Int -> m (Either ParseError ())
540 (PR.dropWhile (<= value))
541 (PR.dropWhile (<= value))
545-------------------------------------------------------------------------------
547-------------------------------------------------------------------------------
550span :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
551span value = Stream.parse (PR.span (<= (value `div` 2)) Fold.drain Fold.drain)
554spanBy :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
556 Stream.parse (PR.spanBy (\_ i -> i <= (value `div` 2)) Fold.drain Fold.drain)
558{-# INLINE spanByRolling #-}
559spanByRolling :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
561 Stream.parse (PR.spanByRolling (\_ i -> i <= value `div` 2) Fold.drain Fold.drain)
563parseManyChunksOfSum :: Int -> Handle -> IO Int
564parseManyChunksOfSum n inh =
565 Stream.fold Fold.length
567 (PR.fromFold $ Fold.take n Fold.sum)
568 (Stream.unfold Handle.reader inh)
570-------------------------------------------------------------------------------
571-- Parsers in which -fspec-constr-recursive=16 is problematic
572-------------------------------------------------------------------------------
574-- XXX -fspec-constr-recursive=16 makes GHC go beserk when compiling these.
575-- We need to fix GHC so that we can have better control over that option or do
576-- not have to rely on it.
578{-# INLINE lookAhead #-}
579lookAhead :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
581 Stream.parse (PR.lookAhead (PR.takeWhile (<= value) Fold.drain) $> ())
583-- XXX The timing of this increased 3x after the stepify extract changes.
584{-# INLINE sequenceA_ #-}
585sequenceA_ :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
587 Stream.parse (F.sequenceA_ $ replicate value (PR.satisfy (> 0)))
589-- quadratic complexity
590{-# INLINE sequenceA #-}
591sequenceA :: Monad m => Int -> Stream m Int -> m Int
592sequenceA value xs = do
593 x <- Stream.parse (TR.sequenceA (replicate value (PR.satisfy (> 0)))) xs
596-- quadratic complexity
597{-# INLINE sequence #-}
598sequence :: Monad m => Int -> Stream m Int -> m Int
599sequence value xs = do
600 x <- Stream.parse (TR.sequence (replicate value (PR.satisfy (> 0)))) xs
603{-# INLINE sequence_ #-}
604sequence_ :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
606 Stream.parse (foldr f (return ()) (replicate value (PR.takeBetween 0 1 Fold.drain))) xs
611 f m k = m >>= (\_ -> k)
613-- choice using the "Alternative" instance with direct style parser type has
614-- quadratic performance complexity.
616{-# INLINE choiceAsum #-}
617choiceAsum :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
619 Stream.parse (F.asum (replicate value (PR.satisfy (< 0)))
620 AP.<|> PR.satisfy (> 0))
624choice :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
627 (PR.choice (replicate value (PR.satisfy (< 0))) AP.<|> PR.satisfy (> 0))
630-------------------------------------------------------------------------------
631-- Parsing with unfolds
632-------------------------------------------------------------------------------
634{-# INLINE parseManyUnfoldArrays #-}
635parseManyUnfoldArrays :: Int -> [Array.Array Int] -> IO ()
636parseManyUnfoldArrays count arrays = do
637 let src = Producer.source (Just (Producer.OuterLoop arrays))
638 let parser = PR.fromFold (Fold.take count Fold.drain)
641 $ Producer.concat Producer.fromList Array.producer
643 Producer.simplify (Producer.parseMany parser readSrc)
644 Stream.fold Fold.drain $ Stream.unfold streamParser src
646-------------------------------------------------------------------------------
647-- Stream transformation
648-------------------------------------------------------------------------------
650{-# INLINE parseMany #-}
651parseMany :: Monad m => Int -> Stream m Int -> m ()
653 Stream.fold Fold.drain
655 . Stream.catRights . Stream.parseMany (PR.fromFold $ Fold.take n Fold.mconcat)
658{-# INLINE parseManyGroupBy #-}
659parseManyGroupBy :: Monad m => (Int -> Int -> Bool) -> Stream m Int -> m ()
660parseManyGroupBy cmp =
661 Stream.fold Fold.drain . Stream.parseMany (PR.groupBy cmp Fold.drain)
663{-# INLINE parseManyGroupsRolling #-}
664parseManyGroupsRolling :: Monad m => Bool -> Stream m Int -> m ()
665parseManyGroupsRolling b =
666 Stream.fold Fold.drain
667 . Stream.parseMany (PR.groupByRolling (\_ _ -> b) Fold.drain)
669{-# INLINE parseManyGroupsRollingEither #-}
670parseManyGroupsRollingEither :: Monad m =>
671 (Int -> Int -> Bool) -> Int -> m ()
672parseManyGroupsRollingEither cmp value = do
673 sourceUnfoldrM value 1
674 & Stream.parseMany (PR.groupByRollingEither cmp Fold.drain Fold.drain)
675 & Stream.fold Fold.drain
677{-# INLINE parseManyGroupsRollingEitherAlt #-}
678parseManyGroupsRollingEitherAlt :: Monad m =>
679 (Int -> Int -> Bool) -> Int -> m ()
680parseManyGroupsRollingEitherAlt cmp value = do
681 sourceUnfoldrM value 1
682 -- Make the input unsorted.
683 & fmap (\x -> if even x then x + 2 else x)
684 & Stream.parseMany (PR.groupByRollingEither cmp Fold.drain Fold.drain)
685 & Stream.fold Fold.drain
687{-# INLINE parseIterate #-}
688parseIterate :: Monad m => Int -> Stream m Int -> m ()
690 Stream.fold Fold.drain
693 . Stream.parseIterate
694 (PR.fromFold . Fold.take n . Fold.sconcat)
698{-# INLINE concatSequence #-}
699concatSequence :: Monad m => Stream m Int -> m (Either ParseError ())
701 Stream.parse $ PR.sequence (Stream.repeat PR.one) Fold.drain
703-------------------------------------------------------------------------------
705-------------------------------------------------------------------------------
708moduleName = "Data.Parser"
710instance NFData ParseError where
712 rnf (ParseError x) = rnf x
714o_1_space_serial :: Int -> [Benchmark]
715o_1_space_serial value =
716 [ benchIOSink value "takeBetween" $ takeBetween value
717 , benchIOSink value "takeEQ" $ takeEQ value
718 , benchIOSink value "takeGE" $ takeGE value
719 , benchIOSink value "takeWhile" $ takeWhile value
720 , benchIOSink value "takeWhileP" $ takeWhileP value
721 , benchIOSink value "takeP" $ takeP value
722 , benchIOSink value "dropWhile" $ dropWhile value
723 , benchIOSink value "takeStartBy" $ takeStartBy value
724 , benchIOSink value "takeEndBy_" $ takeEndBy_ value
725 , benchIOSink value "groupBy" $ groupBy
726 , benchIOSink value "groupByRolling" $ groupByRolling
727 , benchIOSink value "wordBy" $ wordBy value
728 , benchIOSink value "sepBy (words)" sepByWords
729 , benchIOSink value "sepByAll (words)" sepByAllWords
730 , benchIOSink value "sepBy1 (words)" sepByWords1
731 , benchIOSink value "deintercalate" $ deintercalate value
732 , benchIOSink value "deintercalate1" $ deintercalate1 value
733 , benchIOSink value "deintercalateAll" $ deintercalateAll value
734 -- Applicative and Monad
735 , benchIOSink value "splitAp2" $ splitAp2 value
736 , benchIOSink value "splitAp4" $ splitAp4 value
737 , benchIOSink value "splitAp8" $ splitAp8 value
738 , benchIOSink value "splitApBefore" $ splitApBefore value
739 , benchIOSink value "splitApAfter" $ splitApAfter value
740 , benchIOSink value "splitWith2" $ splitWith2 value
741 , benchIOSink value "span" $ span value
742 , benchIOSink value "spanBy" $ spanBy value
743 , benchIOSink value "spanByRolling" $ spanByRolling value
744 , benchIOSink value "monad2" $ monad value
745 , benchIOSink value "monad4" $ monad4 value
746 , benchIOSink value "monad8" $ monad8 value
748 , benchIOSink value "alt2parseMany" $ altSmall value
749 , benchIOSink value "alt2" $ alt2 value
750 , benchIOSink value "alt4" $ alt4 value
751 , benchIOSink value "alt8" $ alt8 value
752 , benchIOSink value "alt16" $ alt16 value
753 , benchIOSink value "many" many
754 , benchIOSink value "many (wordBy even)" $ manyWordByEven
755 , benchIOSink value "some" some
756 , benchIOSink value "manyTill" $ manyTill value
757 , benchIOSink value "parseMany" $ parseMany value
758 , benchIOSink value "parseMany (take 1)" (parseMany 1)
759 , benchIOSink value "parseMany (take all)" (parseMany value)
760 , benchIOSink value "parseMany (groupBy (<))" (parseManyGroupBy (<))
761 , benchIOSink value "parseMany (groupBy (==))" (parseManyGroupBy (==))
762 , benchIOSink value "parseMany groupRollingBy (bound groups)"
763 $ parseManyGroupsRolling False
764 , benchIOSink value "parseMany groupRollingBy (1 group)"
765 $ parseManyGroupsRolling True
766 , bench "parseMany groupRollingByEither (Left)"
767 $ nfIO $ parseManyGroupsRollingEitherLeft
768 , bench "parseMany groupRollingByEither (Right)"
769 $ nfIO $ parseManyGroupsRollingEitherRight
770 , bench "parseMany groupRollingByEither (Alternating)"
771 $ nfIO $ parseManyGroupsRollingEitherAlt1
772 , benchIOSink value "parseIterate (take 1)" (parseIterate 1)
773 , benchIOSink value "parseIterate (take all)" (parseIterate value)
774 , benchIOSink value "concatSequence" concatSequence
776 , benchIOSink value "tee" $ teeAllAny value
777 , benchIOSink value "teeFst" $ teeFstAllAny value
778 , benchIOSink value "shortest" $ shortestAllAny value
779 , benchIOSink value "longest" $ longestAllAny value
781 , benchIOSink value "streamEqBy" (streamEqBy value)
786 {-# NOINLINE parseManyGroupsRollingEitherLeft #-}
787 parseManyGroupsRollingEitherLeft = parseManyGroupsRollingEither (<) value
789 {-# NOINLINE parseManyGroupsRollingEitherRight #-}
790 parseManyGroupsRollingEitherRight = parseManyGroupsRollingEither (>) value
792 {-# NOINLINE parseManyGroupsRollingEitherAlt1 #-}
793 parseManyGroupsRollingEitherAlt1 =
794 parseManyGroupsRollingEitherAlt (>) value
796o_1_space_filesystem :: BenchEnv -> [Benchmark]
797o_1_space_filesystem env =
798 [ mkBench ("S.parseMany (Fold.take " ++ show (bigSize env) ++ " Fold.sum)") env
799 $ \inh _ -> noinline parseManyChunksOfSum (bigSize env) inh
800 , mkBench "S.parseMany (Fold.take 1 Fold.sum)" env
801 $ \inh _ -> inline parseManyChunksOfSum 1 inh
804o_1_space_serial_unfold :: Int -> [Array.Array Int] -> [Benchmark]
805o_1_space_serial_unfold bound arrays =
806 [ bench "parseMany/Unfold/1000 arrays/take all"
807 $ nfIO $ parseManyUnfoldArrays bound arrays
808 , bench "parseMany/Unfold/1000 arrays/take 1"
809 $ nfIO $ parseManyUnfoldArrays 1 arrays
812o_n_heap_serial :: Int -> [Benchmark]
813o_n_heap_serial value =
815 -- lookahead benchmark holds the entire input till end
816 benchIOSink value "lookAhead" $ lookAhead value
818 -- o-n-heap because of backtracking
819 , benchIOSrc sourceEscapedFrames value "takeFramedByEsc_"
820 $ takeFramedByEsc_ value
822 -- non-linear time complexity (parserD)
823 , benchIOSink value "split_" $ split_ value
824 -- XXX Takes lot of space when run on a long stream, why?
825 , benchIOSink value "monad16" $ monad16 value
827 -- These show non-linear time complexity.
828 -- They accumulate the results in a list.
829 , benchIOSink value "sepBy1" sepBy1
830 , benchIOSink value "manyAlt" manyAlt
831 , benchIOSink value "someAlt" someAlt
832 , benchIOSink value "listEqBy" (listEqBy value)
835-- accumulate results in a list in IO
836o_n_space_serial :: Int -> [Benchmark]
837o_n_space_serial value =
838 [ benchIOSink value "sequenceA/100" $ sequenceA (value `div` 100)
839 , benchIOSink value "sequenceA_/100" $ sequenceA_ (value `div` 100)
840 , benchIOSink value "sequence/100" $ sequence (value `div` 100)
841 , benchIOSink value "sequence_/100" $ sequence_ (value `div` 100)
842 , benchIOSink value "choice (asum)/100" $ choiceAsum (value `div` 100)
843 -- , benchIOSink value "choice/100" $ choice (value `div` 100)
846-------------------------------------------------------------------------------
848-------------------------------------------------------------------------------
853 env <- mkHandleBenchEnv
854 runWithCLIOptsEnv defaultStreamSize alloc (allBenchmarks env)
858 alloc value = Stream.fold Fold.toList $ Stream.chunksOf 100 $ sourceUnfoldrM value 0
860 allBenchmarks env arrays value =
861 [ bgroup (o_1_space_prefix moduleName) (o_1_space_serial value)
863 (o_1_space_prefix moduleName ++ "/filesystem")
864 (o_1_space_filesystem env)
865 , bgroup (o_1_space_prefix moduleName)
866 (o_1_space_serial_unfold value arrays)
867 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
868 , bgroup (o_n_space_prefix moduleName) (o_n_space_serial value)
871 -- Enable FUSION_CHECK macro at the beginning of the file
872 -- Enable one benchmark below, and run the benchmark
873 -- Check the .dump-simpl output
875 -- let input = sourceUnfoldrM value 1
876 -- manyTill value input
877 -- deintercalate value input
878 -- deintercalate1 value input
879 -- deintercalateAll value input
881 -- sepByAllWords input
884 takeFramedByEsc_ value (sourceEscapedFrames value 1)
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