@@ -1,3 +1,10 @@
1+{-# OPTIONS_GHC -Wno-deprecations #-}
2+
3+#undef FUSION_CHECK
4+#ifdef FUSION_CHECK
5+{-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dsuppress-all #-}
6+#endif
7+
18-- |
29-- Module : Streamly.Benchmark.Data.Parser
310-- Copyright : (c) 2020 Composewell Technologies
@@ -7,43 +14,42 @@
714
815{-# LANGUAGE CPP #-}
916{-# LANGUAGE FlexibleContexts #-}
17+{-# LANGUAGE ScopedTypeVariables #-}
18+{-# OPTIONS_GHC -Wno-orphans #-}
1019
1120module Main
1221 (
1322 main
1423 ) where
1524
25+import Control.Applicative ((<|>))
1626import Control.DeepSeq (NFData(..))
17−import Control.Monad.Catch (MonadCatch)
18−import Data.Foldable (asum)
27+import Data.Function ((&))
1928import Data.Functor (($>))
20−import Data.Maybe (fromMaybe)
2129import Data.Monoid (Sum(..))
2230import GHC.Magic (inline)
23−#if __GLASGOW_HASKELL__ >= 802
2431import GHC.Magic (noinline)
25−#else
26−#define noinline
27−#endif
2832import System.IO (Handle)
2933import System.Random (randomRIO)
30−import Prelude
31− hiding (any, all, take, sequence, sequence_, sequenceA, takeWhile)
34+import Streamly.Internal.Data.Fold (Fold(..))
35+import Streamly.Internal.Data.Parser
36+ (ParseError(..), Parser(..), Initial(..), Step(..))
37+import Streamly.Internal.Data.Stream (Stream)
38+import Prelude hiding
39+ (any, all, take, sequence, sequence_, sequenceA, takeWhile, dropWhile, span)
3240
33−import qualified Data.Traversable as TR
34−import qualified Data.Foldable as F
3541import qualified Control.Applicative as AP
42+import qualified Data.Foldable as F
43+import qualified Data.Traversable as TR
3644import qualified Streamly.FileSystem.Handle as Handle
37−import qualified Streamly.Prelude as S
38−import qualified Streamly.Internal.Data.Array.Foreign as Array
39−import qualified Streamly.Internal.Data.Fold as FL
45+import qualified Streamly.Internal.Data.Array as Array
46+import qualified Streamly.Internal.Data.Fold as Fold
4047import qualified Streamly.Internal.Data.Parser as PR
41−import qualified Streamly.Internal.Data.Stream.IsStream as IP
48+import qualified Streamly.Data.Stream as Stream
4249import qualified Streamly.Internal.Data.Producer as Producer
43−import qualified Streamly.Internal.Data.Producer.Source as Source
50+import qualified Streamly.Internal.Data.Stream as Stream
4451
45−import Gauge hiding (env)
46−import Streamly.Prelude (SerialT)
52+import Test.Tasty.Bench hiding (env)
4753import Streamly.Benchmark.Common
4854import Streamly.Benchmark.Common.Handle
4955
@@ -54,19 +60,59 @@ import Streamly.Benchmark.Common.Handle
5460-- XXX these can be moved to the common module
5561
5662{-# INLINE sourceUnfoldrM #-}
57−sourceUnfoldrM :: (S.IsStream t, S.MonadAsync m) => Int -> Int -> t m Int
58−sourceUnfoldrM value n = S.unfoldrM step n
63+sourceUnfoldrM :: Monad m => Int -> Int -> Stream m Int
64+sourceUnfoldrM value n = Stream.unfoldrM step n
5965 where
6066 step cnt =
6167 if cnt > n + value
6268 then return Nothing
6369 else return (Just (cnt, cnt + 1))
6470
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
74+-- sequence of `}`.
75+{-# INLINE sourceEscapedFrames #-}
76+sourceEscapedFrames ::
77+ Monad m
78+ => Int
79+ -> Int
80+ -> Stream m Char
81+sourceEscapedFrames value n = Stream.unfoldrM step n
82+ where
83+
84+ bs = '\\'
85+ cbOpen = '{'
86+ cbClose = '}'
87+ value1 = value `div` 4
88+
89+ step cnt
90+ | cnt > 4 * value1 = return Nothing
91+ | cnt <= value1 = return $ Just (cbOpen, cnt + 1)
92+ | cnt > 3 * value1 = return $ Just (cbClose, cnt + 1)
93+ | otherwise =
94+ return
95+ $ Just
96+ $ if (cnt - value1) `mod` 2 == 1
97+ then (bs, cnt + 1)
98+ else (cbOpen, cnt + 1)
99+
100+{-# INLINE benchIOSrc #-}
101+benchIOSrc
102+ :: NFData b
103+ => (Int -> Int -> Stream IO a)
104+ -> Int
105+ -> String
106+ -> (Stream IO a -> IO b)
107+ -> Benchmark
108+benchIOSrc src value name f =
109+ bench name $ nfIO $ randomRIO (1,1) >>= f . src value
110+
65111-- | Takes a fold method, and uses it with a default source.
66112{-# INLINE benchIOSink #-}
67113benchIOSink
68− :: (S.IsStream t, NFData b)
69− => Int -> String -> (t IO Int -> IO b) -> Benchmark
114+ :: NFData b
115+ => Int -> String -> (Stream IO Int -> IO b) -> Benchmark
70116benchIOSink value name f =
71117 bench name $ nfIO $ randomRIO (1,1) >>= f . sourceUnfoldrM value
72118
@@ -75,188 +121,451 @@ benchIOSink value name f =
75121-------------------------------------------------------------------------------
76122
77123{-# INLINE takeBetween #-}
78−takeBetween :: MonadCatch m => Int -> SerialT m a -> m ()
79−takeBetween value = IP.parse (PR.takeBetween 0 value FL.drain)
124+takeBetween :: Monad m => Int -> Stream m a -> m (Either ParseError ())
125+takeBetween value = Stream.parse (PR.takeBetween 0 value Fold.drain)
80126
81127{-# INLINE takeEQ #-}
82−takeEQ :: MonadCatch m => Int -> SerialT m a -> m ()
83−takeEQ value = IP.parse (PR.takeEQ value FL.drain)
128+takeEQ :: Monad m => Int -> Stream m a -> m (Either ParseError ())
129+takeEQ value = Stream.parse (PR.takeEQ value Fold.drain)
130+
131+{-# INLINE takeGE #-}
132+takeGE :: Monad m => Int -> Stream m a -> m (Either ParseError ())
133+takeGE value = Stream.parse (PR.takeGE value Fold.drain)
134+
135+{-# INLINE dropWhile #-}
136+dropWhile :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
137+dropWhile value = Stream.parse (PR.dropWhile (<= value))
84138
85−{-# INLINE drainWhile #-}
86−drainWhile :: MonadCatch m => Int -> SerialT m Int -> m ()
87−drainWhile value = IP.parse (PR.drainWhile (<= value))
139+{-# INLINE takeStartBy #-}
140+takeStartBy :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
141+takeStartBy value stream = do
142+ let stream2 = value `Stream.cons` stream
143+ Stream.parse (PR.takeStartBy (== value) Fold.drain) stream2
88144
89−{-# INLINE sliceBeginWith #-}
90−sliceBeginWith :: MonadCatch m => Int -> SerialT m Int -> m ()
91−sliceBeginWith value stream = do
92− stream1 <- return . fromMaybe (S.fromPure (value + 1)) =<< S.tail stream
93− let stream2 = value `S.cons` stream1
94− IP.parse (PR.sliceBeginWith (== value) FL.drain) stream2
145+takeFramedByEsc_ :: Monad m => Int -> Stream m Char -> m (Either ParseError ())
146+takeFramedByEsc_ _ = Stream.parse parser
147+
148+ where
149+
150+ isEsc = (== '\\')
151+ isBegin = (== '{')
152+ isEnd = (== '}')
153+
154+ parser = PR.takeFramedByEsc_ isEsc isBegin isEnd Fold.drain
155+
156+{-# INLINE listEqBy #-}
157+listEqBy :: Int -> Stream IO Int -> IO (Either ParseError [Int])
158+listEqBy len = Stream.parse (PR.listEqBy (==) [1 .. len])
159+
160+{-# INLINE streamEqBy #-}
161+streamEqBy :: Int -> Stream IO Int -> IO (Either ParseError ())
162+streamEqBy len = Stream.parse (PR.streamEqBy (==) (Stream.enumerateFromTo 1 len))
95163
96164{-# INLINE takeWhile #-}
97−takeWhile :: MonadCatch m => Int -> SerialT m Int -> m ()
98−takeWhile value = IP.parse (PR.takeWhile (<= value) FL.drain)
165+takeWhile :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
166+takeWhile value = Stream.parse (PR.takeWhile (<= value) Fold.drain)
167+
168+takeWhileP :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
169+takeWhileP value =
170+ Stream.parse (PR.takeWhileP (<= value) (PR.takeWhile (<= value - 1) Fold.drain))
99171
100172{-# INLINE takeP #-}
101−takeP :: MonadCatch m => Int -> SerialT m a -> m ()
102−takeP value = IP.parse (PR.takeP value (PR.fromFold FL.drain))
173+takeP :: Monad m => Int -> Stream m a -> m (Either ParseError ())
174+takeP value = Stream.parse (PR.takeP value (PR.fromFold Fold.drain))
103175
104176{-# INLINE groupBy #-}
105−groupBy :: MonadCatch m => SerialT m Int -> m ()
106−groupBy = IP.parse (PR.groupBy (<=) FL.drain)
177+groupBy :: Monad m => Stream m Int -> m (Either ParseError ())
178+groupBy = Stream.parse (PR.groupBy (<=) Fold.drain)
107179
108180{-# INLINE groupByRolling #-}
109−groupByRolling :: MonadCatch m => SerialT m Int -> m ()
110−groupByRolling = IP.parse (PR.groupByRolling (<=) FL.drain)
181+groupByRolling :: Monad m => Stream m Int -> m (Either ParseError ())
182+groupByRolling = Stream.parse (PR.groupByRolling (<=) Fold.drain)
111183
112184{-# INLINE wordBy #-}
113−wordBy :: MonadCatch m => Int -> SerialT m Int -> m ()
114−wordBy value = IP.parse (PR.wordBy (>= value) FL.drain)
185+wordBy :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
186+wordBy value = Stream.parse (PR.wordBy (>= value) Fold.drain)
187+
188+{-# INLINE sepByWords #-}
189+sepByWords :: Monad m => Stream m Int -> m (Either ParseError ())
190+sepByWords = Stream.parse (wrds even Fold.drain)
191+ where
192+ wrds p = PR.sepBy (PR.takeWhile (not . p) Fold.drain) (PR.dropWhile p)
193+
194+{-# INLINE sepByAllWords #-}
195+sepByAllWords :: Monad m => Stream m Int -> m (Either ParseError ())
196+sepByAllWords = Stream.parse (wrds even Fold.drain)
197+ where
198+ wrds p = PR.sepByAll (PR.takeWhile (not . p) Fold.drain) (PR.dropWhile p)
199+
200+-- Returning a list to compare with the sepBy1 in ParserK
201+{-# INLINE sepBy1 #-}
202+sepBy1 :: Monad m => Stream m Int -> m (Either ParseError [Int])
203+sepBy1 xs = do
204+ Stream.parse (PR.sepBy1 (PR.satisfy odd) (PR.satisfy even) Fold.toList) xs
205+
206+{-# INLINE sepByWords1 #-}
207+sepByWords1 :: Monad m => Stream m Int -> m (Either ParseError ())
208+sepByWords1 = Stream.parse (wrds even Fold.drain)
209+ where
210+ wrds p = PR.sepBy1 (PR.takeWhile (not . p) Fold.drain) (PR.dropWhile p)
211+
212+{-# INLINE deintercalate #-}
213+deintercalate :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
214+deintercalate _ = Stream.parse (partition even)
215+
216+ where
217+
218+ partition p =
219+ PR.deintercalate
220+ (PR.takeWhile (not . p) Fold.sum) (PR.takeWhile p Fold.sum) Fold.drain
221+
222+{-# INLINE deintercalate1 #-}
223+deintercalate1 :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
224+deintercalate1 _ = Stream.parse (partition even)
225+
226+ where
227+
228+ partition p =
229+ PR.deintercalate1
230+ (PR.takeWhile (not . p) Fold.sum) (PR.takeWhile p Fold.sum) Fold.drain
231+
232+{-# INLINE deintercalateAll #-}
233+deintercalateAll :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
234+deintercalateAll _ = Stream.parse (partition even)
235+
236+ where
237+
238+ partition p =
239+ PR.deintercalateAll
240+ (PR.takeWhile (not . p) Fold.sum) (PR.takeWhile p Fold.sum) Fold.drain
115241
116242{-# INLINE manyWordByEven #-}
117−manyWordByEven :: MonadCatch m => SerialT m Int -> m ()
118−manyWordByEven = IP.parse (PR.many (PR.wordBy (Prelude.even) FL.drain) FL.drain)
243+manyWordByEven :: Monad m => Stream m Int -> m (Either ParseError ())
244+manyWordByEven = Stream.parse (PR.many (PR.wordBy even Fold.drain) Fold.drain)
119245
120246{-# INLINE many #-}
121−many :: MonadCatch m => SerialT m Int -> m Int
122−many = IP.parse (PR.many (PR.satisfy (> 0)) FL.length)
247+many :: Monad m => Stream m Int -> m (Either ParseError Int)
248+many = Stream.parse (PR.many (PR.satisfy (> 0)) Fold.length)
123249
124250{-# INLINE manyAlt #-}
125−manyAlt :: MonadCatch m => SerialT m Int -> m Int
251+manyAlt :: Monad m => Stream m Int -> m Int
126252manyAlt xs = do
127− x <- IP.parse (AP.many (PR.satisfy (> 0))) xs
253+ x <- Stream.parse (AP.many (PR.satisfy (> 0))) xs
128254 return $ Prelude.length x
129255
130256{-# INLINE some #-}
131−some :: MonadCatch m => SerialT m Int -> m Int
132−some = IP.parse (PR.some (PR.satisfy (> 0)) FL.length)
257+some :: Monad m => Stream m Int -> m (Either ParseError Int)
258+some = Stream.parse (PR.some (PR.satisfy (> 0)) Fold.length)
133259
134260{-# INLINE someAlt #-}
135−someAlt :: MonadCatch m => SerialT m Int -> m Int
261+someAlt :: Monad m => Stream m Int -> m Int
136262someAlt xs = do
137− x <- IP.parse (AP.some (PR.satisfy (> 0))) xs
263+ x <- Stream.parse (AP.some (PR.satisfy (> 0))) xs
138264 return $ Prelude.length x
139265
140266{-# INLINE manyTill #-}
141−manyTill :: MonadCatch m => Int -> SerialT m Int -> m Int
267+manyTill :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
142268manyTill value =
143− IP.parse (PR.manyTill (PR.satisfy (> 0)) (PR.satisfy (== value)) FL.length)
269+ Stream.parse (PR.manyTill (PR.satisfy (> 0)) (PR.satisfy (== value)) Fold.length)
144270
145−{-# INLINE splitAp #-}
146−splitAp :: MonadCatch m
147− => Int -> SerialT m Int -> m ((), ())
148−splitAp value =
149− IP.parse
271+{-# INLINE splitAp2 #-}
272+splitAp2 :: Monad m
273+ => Int -> Stream m Int -> m (Either ParseError ((), ()))
274+splitAp2 value =
275+ Stream.parse
150276 ((,)
151− <$> PR.drainWhile (<= (value `div` 2))
152− <*> PR.drainWhile (<= value)
277+ <$> PR.dropWhile (<= (value `div` 2))
278+ <*> PR.dropWhile (<= value)
279+ )
280+
281+{-# INLINE splitAp4 #-}
282+splitAp4 :: Monad m
283+ => Int -> Stream m Int -> m (Either ParseError ())
284+splitAp4 value =
285+ Stream.parse
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)
291+ )
292+
293+{-# INLINE splitAp8 #-}
294+splitAp8 :: Monad m
295+ => Int -> Stream m Int -> m (Either ParseError ())
296+splitAp8 value =
297+ Stream.parse
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)
153307 )
154308
155309{-# INLINE splitApBefore #-}
156−splitApBefore :: MonadCatch m
157− => Int -> SerialT m Int -> m ()
310+splitApBefore :: Monad m
311+ => Int -> Stream m Int -> m (Either ParseError ())
158312splitApBefore value =
159− IP.parse
160− ( PR.drainWhile (<= (value `div` 2))
161− *> PR.drainWhile (<= value)
313+ Stream.parse
314+ ( PR.dropWhile (<= (value `div` 2))
315+ *> PR.dropWhile (<= value)
162316 )
163317
164318{-# INLINE splitApAfter #-}
165−splitApAfter :: MonadCatch m
166− => Int -> SerialT m Int -> m ()
319+splitApAfter :: Monad m
320+ => Int -> Stream m Int -> m (Either ParseError ())
167321splitApAfter value =
168− IP.parse
169− ( PR.drainWhile (<= (value `div` 2))
170− <* PR.drainWhile (<= value)
322+ Stream.parse
323+ ( PR.dropWhile (<= (value `div` 2))
324+ <* PR.dropWhile (<= value)
171325 )
172326
173−{-# INLINE serialWith #-}
174−serialWith :: MonadCatch m
175− => Int -> SerialT m Int -> m ((), ())
176−serialWith value =
177− IP.parse
178− (PR.serialWith (,)
179− (PR.drainWhile (<= (value `div` 2)))
180− (PR.drainWhile (<= value))
327+{-# INLINE splitWith2 #-}
328+splitWith2 :: Monad m
329+ => Int -> Stream m Int -> m (Either ParseError ((), ()))
330+splitWith2 value =
331+ Stream.parse
332+ (PR.splitWith (,)
333+ (PR.dropWhile (<= (value `div` 2)))
334+ (PR.dropWhile (<= value))
181335 )
182336
183337{-# INLINE split_ #-}
184−split_ :: MonadCatch m
185− => Int -> SerialT m Int -> m ()
338+split_ :: Monad m
339+ => Int -> Stream m Int -> m (Either ParseError ())
186340split_ value =
187− IP.parse
341+ Stream.parse
188342 (PR.split_
189− (PR.drainWhile (<= (value `div` 2)))
190− (PR.drainWhile (<= value))
343+ (PR.dropWhile (<= (value `div` 2)))
344+ (PR.dropWhile (<= value))
191345 )
192346
193−{-# INLINE sliceSepByP #-}
194−sliceSepByP :: MonadCatch m
195− => Int -> SerialT m Int -> m()
196−sliceSepByP value = IP.parse (PR.sliceSepByP (>= value) (PR.fromFold FL.drain))
347+-- XXX dropWhile with applicative does not fuse
348+-- PR.dropWhile (<= (value * 1 `div` 4)) *> PR.die "alt"
349+{-# INLINE takeWhileFail #-}
350+takeWhileFail :: Monad m => (a -> Bool) -> Fold m a b -> Parser a m b
351+takeWhileFail predicate (Fold fstep finitial _ ffinal) =
352+ Parser step initial extract
353+
354+ where
197355
356+ initial = do
357+ res <- finitial
358+ return $ case res of
359+ Fold.Partial s -> IPartial s
360+ Fold.Done b -> IDone b
361+
362+ step s a =
363+ if predicate a
364+ then do
365+ fres <- fstep s a
366+ return
367+ $ case fres of
368+ Fold.Partial s1 -> Partial 0 s1
369+ Fold.Done b -> Done 0 b
370+ else return $ Error "fail"
371+
372+ extract s = fmap (Done 0) (ffinal s)
373+
374+{-# INLINE alt2 #-}
375+alt2 :: Monad m
376+ => Int -> Stream m Int -> m (Either ParseError ())
377+alt2 value =
378+ Stream.parse
379+ (PR.alt
380+ (takeWhileFail (<= (value `div` 2)) Fold.drain)
381+ (PR.dropWhile (<= value))
382+ )
383+
384+{-# INLINE alt4 #-}
385+alt4 :: Monad m
386+ => Int -> Stream m Int -> m (Either ParseError ())
387+alt4 value =
388+ Stream.parse
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)
393+ )
394+
395+{-# INLINE alt8 #-}
396+alt8 :: Monad m
397+ => Int -> Stream m Int -> m (Either ParseError ())
398+alt8 value =
399+ Stream.parse
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)
408+ )
409+
410+{-# INLINE alt16 #-}
411+alt16 :: Monad m
412+ => Int -> Stream m Int -> m (Either ParseError ())
413+alt16 value =
414+ Stream.parse
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)
430+ )
431+
432+{-# INLINE altSmall #-}
433+altSmall :: Monad m
434+ => Int -> Stream m Int -> m ()
435+altSmall value =
436+ Stream.fold Fold.drain .
437+ Stream.parseMany
438+ (PR.alt
439+ (PR.satisfy (>= value) *> PR.die "alt")
440+ (PR.satisfy (<= value))
441+ )
442+
443+{-# INLINE monad #-}
444+monad :: Monad m
445+ => Int -> Stream m Int -> m (Either ParseError ())
446+monad value =
447+ Stream.parse
448+ $ do
449+ PR.dropWhile (<= (value `div` 2))
450+ PR.dropWhile (<= value)
451+
452+{-# INLINE monad4 #-}
453+monad4 :: Monad m
454+ => Int -> Stream m Int -> m (Either ParseError ())
455+monad4 value =
456+ Stream.parse $ do
457+ PR.dropWhile (<= (value `div` 4))
458+ PR.dropWhile (<= (value `div` 2))
459+ PR.dropWhile (<= (value * 3 `div` 4))
460+ PR.dropWhile (<= value)
461+
462+{-# INLINE monad8 #-}
463+monad8 :: Monad m
464+ => Int -> Stream m Int -> m (Either ParseError ())
465+monad8 value =
466+ Stream.parse $ do
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)
475+
476+{-# INLINE monad16 #-}
477+monad16 :: Monad m
478+ => Int -> Stream m Int -> m (Either ParseError ())
479+monad16 value =
480+ Stream.parse $ do
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)
497+
498+{-# INLINE takeEndBy_ #-}
499+takeEndBy_ :: Monad m
500+ => Int -> Stream m Int -> m (Either ParseError ())
501+takeEndBy_ value = Stream.parse (PR.takeEndBy_ (>= value) (PR.fromFold Fold.drain))
502+
503+{-
198504{-# INLINE teeAllAny #-}
199−teeAllAny :: MonadCatch m
200− => Int -> SerialT m Int -> m ((), ())
505+teeAllAny :: Monad m
506+ => Int -> Stream m Int -> m ((), ())
201507teeAllAny value =
202− IP.parse
508+ Stream.parse
203509 (PR.teeWith (,)
204− (PR.drainWhile (<= value))
205− (PR.drainWhile (<= value))
510+ (PR.dropWhile (<= value))
511+ (PR.dropWhile (<= value))
206512 )
207513
208514{-# INLINE teeFstAllAny #-}
209−teeFstAllAny :: MonadCatch m
210− => Int -> SerialT m Int -> m ((), ())
515+teeFstAllAny :: Monad m
516+ => Int -> Stream m Int -> m ((), ())
211517teeFstAllAny value =
212− IP.parse
518+ Stream.parse
213519 (PR.teeWithFst (,)
214− (PR.drainWhile (<= value))
215− (PR.drainWhile (<= value))
520+ (PR.dropWhile (<= value))
521+ (PR.dropWhile (<= value))
216522 )
217523
218524{-# INLINE shortestAllAny #-}
219−shortestAllAny :: MonadCatch m
220− => Int -> SerialT m Int -> m ()
525+shortestAllAny :: Monad m
526+ => Int -> Stream m Int -> m (Either ParseError ())
221527shortestAllAny value =
222− IP.parse
528+ Stream.parse
223529 (PR.shortest
224− (PR.drainWhile (<= value))
225− (PR.drainWhile (<= value))
530+ (PR.dropWhile (<= value))
531+ (PR.dropWhile (<= value))
226532 )
227533
228534{-# INLINE longestAllAny #-}
229−longestAllAny :: MonadCatch m
230− => Int -> SerialT m Int -> m ()
535+longestAllAny :: Monad m
536+ => Int -> Stream m Int -> m (Either ParseError ())
231537longestAllAny value =
232− IP.parse
538+ Stream.parse
233539 (PR.longest
234− (PR.drainWhile (<= value))
235− (PR.drainWhile (<= value))
540+ (PR.dropWhile (<= value))
541+ (PR.dropWhile (<= value))
236542 )
237−
238−parseManyChunksOfSum :: Int -> Handle -> IO Int
239−parseManyChunksOfSum n inh =
240− S.length
241− $ IP.parseMany
242− (PR.fromFold $ FL.take n FL.sum)
243− (S.unfold Handle.read inh)
543+-}
244544
245545-------------------------------------------------------------------------------
246−-- Parsing with unfolds
546+-- Spanning
247547-------------------------------------------------------------------------------
248548
249−{-# INLINE parseManyUnfoldArrays #-}
250−parseManyUnfoldArrays :: Int -> [Array.Array Int] -> IO ()
251−parseManyUnfoldArrays count arrays = do
252− let src = Source.source (Just (Producer.OuterLoop arrays))
253− let parser = PR.fromFold (FL.take count FL.drain)
254− let readSrc =
255− Source.producer
256− $ Producer.concat Producer.fromList Array.producer
257− let streamParser =
258− Producer.simplify (Source.parseMany parser readSrc)
259− S.drain $ S.unfold streamParser src
549+{-# INLINE span #-}
550+span :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
551+span value = Stream.parse (PR.span (<= (value `div` 2)) Fold.drain Fold.drain)
552+
553+{-# INLINE spanBy #-}
554+spanBy :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
555+spanBy value =
556+ Stream.parse (PR.spanBy (\_ i -> i <= (value `div` 2)) Fold.drain Fold.drain)
557+
558+{-# INLINE spanByRolling #-}
559+spanByRolling :: Monad m => Int -> Stream m Int -> m (Either ParseError ((), ()))
560+spanByRolling value =
561+ Stream.parse (PR.spanByRolling (\_ i -> i <= value `div` 2) Fold.drain Fold.drain)
562+
563+parseManyChunksOfSum :: Int -> Handle -> IO Int
564+parseManyChunksOfSum n inh =
565+ Stream.fold Fold.length
566+ $ Stream.parseMany
567+ (PR.fromFold $ Fold.take n Fold.sum)
568+ (Stream.unfold Handle.reader inh)
260569
261570-------------------------------------------------------------------------------
262571-- Parsers in which -fspec-constr-recursive=16 is problematic
@@ -267,63 +576,129 @@ parseManyUnfoldArrays count arrays = do
267576-- not have to rely on it.
268577--
269578{-# INLINE lookAhead #-}
270−lookAhead :: MonadCatch m => Int -> SerialT m Int -> m ()
579+lookAhead :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
271580lookAhead value =
272− IP.parse (PR.lookAhead (PR.takeWhile (<= value) FL.drain) $> ())
581+ Stream.parse (PR.lookAhead (PR.takeWhile (<= value) Fold.drain) $> ())
273582
583+-- XXX The timing of this increased 3x after the stepify extract changes.
584+{-# INLINE sequenceA_ #-}
585+sequenceA_ :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
586+sequenceA_ value =
587+ Stream.parse (F.sequenceA_ $ replicate value (PR.satisfy (> 0)))
588+
589+-- quadratic complexity
274590{-# INLINE sequenceA #-}
275−sequenceA :: MonadCatch m => Int -> SerialT m Int -> m Int
591+sequenceA :: Monad m => Int -> Stream m Int -> m Int
276592sequenceA value xs = do
277− x <- IP.parse (TR.sequenceA (replicate value (PR.satisfy (> 0)))) xs
593+ x <- Stream.parse (TR.sequenceA (replicate value (PR.satisfy (> 0)))) xs
278594 return $ length x
279595
280−{-# INLINE sequenceA_ #-}
281−sequenceA_ :: MonadCatch m => Int -> SerialT m Int -> m ()
282−sequenceA_ value =
283− IP.parse (F.sequenceA_ $ replicate value (PR.satisfy (> 0)))
284−
596+-- quadratic complexity
285597{-# INLINE sequence #-}
286−sequence :: MonadCatch m => Int -> SerialT m Int -> m Int
598+sequence :: Monad m => Int -> Stream m Int -> m Int
287599sequence value xs = do
288− x <- IP.parse (TR.sequence (replicate value (PR.satisfy (> 0)))) xs
600+ x <- Stream.parse (TR.sequence (replicate value (PR.satisfy (> 0)))) xs
289601 return $ length x
290602
291603{-# INLINE sequence_ #-}
292−sequence_ :: MonadCatch m => Int -> SerialT m Int -> m ()
293−sequence_ value =
294− IP.parse (F.sequence_ $ replicate value (PR.satisfy (> 0)))
604+sequence_ :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
605+sequence_ value xs =
606+ Stream.parse (foldr f (return ()) (replicate value (PR.takeBetween 0 1 Fold.drain))) xs
295607
608+ where
609+
610+ {-# INLINE f #-}
611+ f m k = m >>= (\_ -> k)
612+
613+-- choice using the "Alternative" instance with direct style parser type has
614+-- quadratic performance complexity.
615+--
296616{-# INLINE choiceAsum #-}
297−choiceAsum :: MonadCatch m => Int -> SerialT m Int -> m Int
617+choiceAsum :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
298618choiceAsum value =
299− IP.parse (asum (replicate value (PR.satisfy (< 0)))
619+ Stream.parse (F.asum (replicate value (PR.satisfy (< 0)))
300620 AP.<|> PR.satisfy (> 0))
301621
622+{-
302623{-# INLINE choice #-}
303−choice :: MonadCatch m => Int -> SerialT m Int -> m Int
624+choice :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
304625choice value =
305− IP.parse
626+ Stream.parse
306627 (PR.choice (replicate value (PR.satisfy (< 0))) AP.<|> PR.satisfy (> 0))
628+-}
629+
630+-------------------------------------------------------------------------------
631+-- Parsing with unfolds
632+-------------------------------------------------------------------------------
633+
634+{-# INLINE parseManyUnfoldArrays #-}
635+parseManyUnfoldArrays :: Int -> [Array.Array Int] -> IO ()
636+parseManyUnfoldArrays count arrays = do
637+ let src = Producer.source (Just (Producer.OuterLoop arrays))
638+ let parser = PR.fromFold (Fold.take count Fold.drain)
639+ let readSrc =
640+ Producer.producer
641+ $ Producer.concat Producer.fromList Array.producer
642+ let streamParser =
643+ Producer.simplify (Producer.parseMany parser readSrc)
644+ Stream.fold Fold.drain $ Stream.unfold streamParser src
307645
308646-------------------------------------------------------------------------------
309647-- Stream transformation
310648-------------------------------------------------------------------------------
311649
312650{-# INLINE parseMany #-}
313−parseMany :: MonadCatch m => Int -> SerialT m Int -> m ()
651+parseMany :: Monad m => Int -> Stream m Int -> m ()
314652parseMany n =
315− S.drain
316− . S.map getSum
317− . IP.parseMany (PR.fromFold $ FL.take n FL.mconcat)
318− . S.map Sum
653+ Stream.fold Fold.drain
654+ . fmap getSum
655+ . Stream.catRights . Stream.parseMany (PR.fromFold $ Fold.take n Fold.mconcat)
656+ . fmap Sum
657+
658+{-# INLINE parseManyGroupBy #-}
659+parseManyGroupBy :: Monad m => (Int -> Int -> Bool) -> Stream m Int -> m ()
660+parseManyGroupBy cmp =
661+ Stream.fold Fold.drain . Stream.parseMany (PR.groupBy cmp Fold.drain)
662+
663+{-# INLINE parseManyGroupsRolling #-}
664+parseManyGroupsRolling :: Monad m => Bool -> Stream m Int -> m ()
665+parseManyGroupsRolling b =
666+ Stream.fold Fold.drain
667+ . Stream.parseMany (PR.groupByRolling (\_ _ -> b) Fold.drain)
668+
669+{-# INLINE parseManyGroupsRollingEither #-}
670+parseManyGroupsRollingEither :: Monad m =>
671+ (Int -> Int -> Bool) -> Int -> m ()
672+parseManyGroupsRollingEither cmp value = do
673+ sourceUnfoldrM value 1
674+ & Stream.parseMany (PR.groupByRollingEither cmp Fold.drain Fold.drain)
675+ & Stream.fold Fold.drain
676+
677+{-# INLINE parseManyGroupsRollingEitherAlt #-}
678+parseManyGroupsRollingEitherAlt :: Monad m =>
679+ (Int -> Int -> Bool) -> Int -> m ()
680+parseManyGroupsRollingEitherAlt 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
319686
320687{-# INLINE parseIterate #-}
321−parseIterate :: MonadCatch m => Int -> SerialT m Int -> m ()
688+parseIterate :: Monad m => Int -> Stream m Int -> m ()
322689parseIterate n =
323− S.drain
324− . S.map getSum
325− . IP.parseIterate (PR.fromFold . FL.take n . FL.sconcat) (Sum 0)
326− . S.map Sum
690+ Stream.fold Fold.drain
691+ . fmap getSum
692+ . Stream.catRights
693+ . Stream.parseIterate
694+ (PR.fromFold . Fold.take n . Fold.sconcat)
695+ (Sum 0)
696+ . fmap Sum
697+
698+{-# INLINE concatSequence #-}
699+concatSequence :: Monad m => Stream m Int -> m (Either ParseError ())
700+concatSequence =
701+ Stream.parse $ PR.sequence (Stream.repeat PR.one) Fold.drain
327702
328703-------------------------------------------------------------------------------
329704-- Benchmarks
@@ -332,41 +707,95 @@ parseIterate n =
332707moduleName :: String
333708moduleName = "Data.Parser"
334709
710+instance NFData ParseError where
711+ {-# INLINE rnf #-}
712+ rnf (ParseError x) = rnf x
713+
335714o_1_space_serial :: Int -> [Benchmark]
336715o_1_space_serial value =
337716 [ benchIOSink value "takeBetween" $ takeBetween value
338− , benchIOSink value "takeEQ" $ takeEQ value
339717 , benchIOSink value "takeWhile" $ takeWhile value
718+ , benchIOSink value "takeWhileP" $ takeWhileP value
340719 , benchIOSink value "takeP" $ takeP value
341− , benchIOSink value "drainWhile" $ drainWhile value
342− , benchIOSink value "sliceBeginWith" $ sliceBeginWith value
720+ , benchIOSink value "dropWhile" $ dropWhile value
721+ , benchIOSink value "takeStartBy" $ takeStartBy value
722+ , benchIOSink value "takeEndBy_" $ takeEndBy_ value
343723 , benchIOSink value "groupBy" $ groupBy
344724 , benchIOSink value "groupByRolling" $ groupByRolling
345725 , benchIOSink value "wordBy" $ wordBy value
346− , benchIOSink value "splitAp" $ splitAp value
726+ , benchIOSink value "sepBy (words)" sepByWords
727+ , benchIOSink value "sepByAll (words)" sepByAllWords
728+ , benchIOSink value "sepBy1 (words)" sepByWords1
729+ , benchIOSink value "deintercalate" $ deintercalate value
730+ , benchIOSink value "deintercalate1" $ deintercalate1 value
731+ , benchIOSink value "deintercalateAll" $ deintercalateAll value
732+ -- Applicative and Monad
733+ , benchIOSink value "splitAp2" $ splitAp2 value
734+ , benchIOSink value "splitAp4" $ splitAp4 value
735+ , benchIOSink value "splitAp8" $ splitAp8 value
347736 , benchIOSink value "splitApBefore" $ splitApBefore value
348737 , benchIOSink value "splitApAfter" $ splitApAfter value
349− , benchIOSink value "serialWith" $ serialWith value
350− , benchIOSink value "sliceSepByP" $ sliceSepByP value
738+ , benchIOSink value "splitWith2" $ splitWith2 value
739+ , benchIOSink value "span" $ span value
740+ , benchIOSink value "spanBy" $ spanBy value
741+ , benchIOSink value "spanByRolling" $ spanByRolling value
742+ , benchIOSink value "monad2" $ monad value
743+ , benchIOSink value "monad4" $ monad4 value
744+ , benchIOSink value "monad8" $ monad8 value
745+ -- Alternative
746+ , benchIOSink value "alt2parseMany" $ altSmall value
747+ , benchIOSink value "alt2" $ alt2 value
748+ , benchIOSink value "alt4" $ alt4 value
749+ , benchIOSink value "alt8" $ alt8 value
750+ , benchIOSink value "alt16" $ alt16 value
351751 , benchIOSink value "many" many
352752 , benchIOSink value "many (wordBy even)" $ manyWordByEven
353753 , benchIOSink value "some" some
354754 , benchIOSink value "manyTill" $ manyTill value
355− , benchIOSink value "tee" $ teeAllAny value
356− , benchIOSink value "teeFst" $ teeFstAllAny value
357− , benchIOSink value "shortest" $ shortestAllAny value
358− , benchIOSink value "longest" $ longestAllAny value
755+ , benchIOSink value "parseMany" $ parseMany value
359756 , benchIOSink value "parseMany (take 1)" (parseMany 1)
360757 , benchIOSink value "parseMany (take all)" (parseMany value)
758+ , benchIOSink value "parseMany (groupBy (<))" (parseManyGroupBy (<))
759+ , benchIOSink value "parseMany (groupBy (==))" (parseManyGroupBy (==))
760+ , benchIOSink value "parseMany groupRollingBy (bound groups)"
761+ $ parseManyGroupsRolling False
762+ , benchIOSink value "parseMany groupRollingBy (1 group)"
763+ $ parseManyGroupsRolling True
764+ , bench "parseMany groupRollingByEither (Left)"
765+ $ nfIO $ parseManyGroupsRollingEitherLeft
766+ , bench "parseMany groupRollingByEither (Right)"
767+ $ nfIO $ parseManyGroupsRollingEitherRight
768+ , bench "parseMany groupRollingByEither (Alternating)"
769+ $ nfIO $ parseManyGroupsRollingEitherAlt1
361770 , benchIOSink value "parseIterate (take 1)" (parseIterate 1)
362771 , benchIOSink value "parseIterate (take all)" (parseIterate value)
772+ , benchIOSink value "concatSequence" concatSequence
773+ {-
774+ , benchIOSink value "tee" $ teeAllAny value
775+ , benchIOSink value "teeFst" $ teeFstAllAny value
776+ , benchIOSink value "shortest" $ shortestAllAny value
777+ , benchIOSink value "longest" $ longestAllAny value
778+ -}
779+ , benchIOSink value "streamEqBy" (streamEqBy value)
363780 ]
364781
782+ where
783+
784+ {-# NOINLINE parseManyGroupsRollingEitherLeft #-}
785+ parseManyGroupsRollingEitherLeft = parseManyGroupsRollingEither (<) value
786+
787+ {-# NOINLINE parseManyGroupsRollingEitherRight #-}
788+ parseManyGroupsRollingEitherRight = parseManyGroupsRollingEither (>) value
789+
790+ {-# NOINLINE parseManyGroupsRollingEitherAlt1 #-}
791+ parseManyGroupsRollingEitherAlt1 =
792+ parseManyGroupsRollingEitherAlt (>) value
793+
365794o_1_space_filesystem :: BenchEnv -> [Benchmark]
366795o_1_space_filesystem env =
367− [ mkBench ("S.parseMany (FL.take " ++ show (bigSize env) ++ " FL.sum)") env
796+ [ mkBench ("S.parseMany (Fold.take " ++ show (bigSize env) ++ " Fold.sum)") env
368797 $ \inh _ -> noinline parseManyChunksOfSum (bigSize env) inh
369− , mkBench "S.parseMany (FL.take 1 FL.sum)" env
798+ , mkBench "S.parseMany (Fold.take 1 Fold.sum)" env
370799 $ \inh _ -> inline parseManyChunksOfSum 1 inh
371800 ]
372801
@@ -381,26 +810,38 @@ o_1_space_serial_unfold bound arrays =
381810o_n_heap_serial :: Int -> [Benchmark]
382811o_n_heap_serial value =
383812 [
813+ benchIOSink value "takeEQ" $ takeEQ value
814+ , benchIOSink value "takeGE" $ takeGE value
815+
384816 -- lookahead benchmark holds the entire input till end
385− benchIOSink value "lookAhead" $ lookAhead value
817+ , benchIOSink value "lookAhead" $ lookAhead value
386818
387− -- accumulates the results in a list
388− , benchIOSink value "sequence" $ sequence value
389− , benchIOSink value "sequenceA" $ sequenceA value
819+ -- o-n-heap because of backtracking
820+ , benchIOSrc sourceEscapedFrames value "takeFramedByEsc_"
821+ $ takeFramedByEsc_ value
390822
391− -- XXX why should this take O(n) heap, it discards the results?
392− , benchIOSink value "sequence_" $ sequence_ value
393− , benchIOSink value "sequenceA_" $ sequenceA_ value
394823 -- non-linear time complexity (parserD)
395824 , benchIOSink value "split_" $ split_ value
396− -- XXX why O(n) heap?
397− , benchIOSink value "choice (asum)" $ choiceAsum value
398− , benchIOSink value "choice" $ choice value
825+ -- XXX Takes lot of space when run on a long stream, why?
826+ , benchIOSink value "monad16" $ monad16 value
399827
400828 -- These show non-linear time complexity.
401829 -- They accumulate the results in a list.
830+ , benchIOSink value "sepBy1" sepBy1
402831 , benchIOSink value "manyAlt" manyAlt
403832 , benchIOSink value "someAlt" someAlt
833+ , benchIOSink value "listEqBy" (listEqBy value)
834+ ]
835+
836+-- accumulate results in a list in IO
837+o_n_space_serial :: Int -> [Benchmark]
838+o_n_space_serial value =
839+ [ benchIOSink value "sequenceA/100" $ sequenceA (value `div` 100)
840+ , benchIOSink value "sequenceA_/100" $ sequenceA_ (value `div` 100)
841+ , benchIOSink value "sequence/100" $ sequence (value `div` 100)
842+ , benchIOSink value "sequence_/100" $ sequence_ (value `div` 100)
843+ , benchIOSink value "choice (asum)/100" $ choiceAsum (value `div` 100)
844+ -- , benchIOSink value "choice/100" $ choice (value `div` 100)
404845 ]
405846
406847-------------------------------------------------------------------------------
@@ -409,12 +850,13 @@ o_n_heap_serial value =
409850
410851main :: IO ()
411852main = do
853+#ifndef FUSION_CHECK
412854 env <- mkHandleBenchEnv
413855 runWithCLIOptsEnv defaultStreamSize alloc (allBenchmarks env)
414856
415857 where
416858
417− alloc value = IP.toList $ IP.arraysOf 100 $ sourceUnfoldrM value 0
859+ alloc value = Stream.fold Fold.toList $ Stream.chunksOf 100 $ sourceUnfoldrM value 0
418860
419861 allBenchmarks env arrays value =
420862 [ bgroup (o_1_space_prefix moduleName) (o_1_space_serial value)
@@ -424,4 +866,22 @@ main = do
424866 , bgroup (o_1_space_prefix moduleName)
425867 (o_1_space_serial_unfold value arrays)
426868 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
869+ , bgroup (o_n_space_prefix moduleName) (o_n_space_serial value)
427870 ]
871+#else
872+ -- Enable FUSION_CHECK macro at the beginning of the file
873+ -- Enable one benchmark below, and run the benchmark
874+ -- Check the .dump-simpl output
875+ let value = 100000
876+ -- let input = sourceUnfoldrM value 1
877+ -- manyTill value input
878+ -- deintercalate value input
879+ -- deintercalate1 value input
880+ -- deintercalateAll value input
881+ -- sepByWords input
882+ -- sepByAllWords input
883+ -- sepBy1 input
884+ -- sepByWords1 input
885+ takeFramedByEsc_ value (sourceEscapedFrames value 1)
886+ return ()
887+#endif