@@ -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
@@ -74,199 +120,452 @@ benchIOSink value name f =
74120-- Parsers
75121-------------------------------------------------------------------------------
76122
77−{-# INLINE next #-}
78−next :: MonadCatch m => Int -> SerialT m Int -> m (Maybe Int)
79−next value = IP.parse p
80− where
81− p = do
82− m <- PR.next
83− case m of
84− Just i -> if i >= value then pure m else p
85− Nothing -> pure Nothing
86−
87123{-# INLINE takeBetween #-}
88−takeBetween :: MonadCatch m => Int -> SerialT m a -> m ()
89−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)
90126
91127{-# INLINE takeEQ #-}
92−takeEQ :: MonadCatch m => Int -> SerialT m a -> m ()
93−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)
94134
95−{-# INLINE drainWhile #-}
96−drainWhile :: MonadCatch m => Int -> SerialT m Int -> m ()
97−drainWhile value = IP.parse (PR.drainWhile (<= value))
135+{-# INLINE dropWhile #-}
136+dropWhile :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
137+dropWhile value = Stream.parse (PR.dropWhile (<= value))
98138
99−{-# INLINE sliceBeginWith #-}
100−sliceBeginWith :: MonadCatch m => Int -> SerialT m Int -> m ()
101−sliceBeginWith value stream = do
102− stream1 <- return . fromMaybe (S.fromPure (value + 1)) =<< S.tail stream
103− let stream2 = value `S.cons` stream1
104− IP.parse (PR.sliceBeginWith (== value) FL.drain) stream2
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
144+
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))
105163
106164{-# INLINE takeWhile #-}
107−takeWhile :: MonadCatch m => Int -> SerialT m Int -> m ()
108−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))
109171
110172{-# INLINE takeP #-}
111−takeP :: MonadCatch m => Int -> SerialT m a -> m ()
112−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))
113175
114176{-# INLINE groupBy #-}
115−groupBy :: MonadCatch m => SerialT m Int -> m ()
116−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)
117179
118180{-# INLINE groupByRolling #-}
119−groupByRolling :: MonadCatch m => SerialT m Int -> m ()
120−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)
121183
122184{-# INLINE wordBy #-}
123−wordBy :: MonadCatch m => Int -> SerialT m Int -> m ()
124−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
125241
126242{-# INLINE manyWordByEven #-}
127−manyWordByEven :: MonadCatch m => SerialT m Int -> m ()
128−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)
129245
130246{-# INLINE many #-}
131−many :: MonadCatch m => SerialT m Int -> m Int
132−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)
133249
134250{-# INLINE manyAlt #-}
135−manyAlt :: MonadCatch m => SerialT m Int -> m Int
251+manyAlt :: Monad m => Stream m Int -> m Int
136252manyAlt xs = do
137− x <- IP.parse (AP.many (PR.satisfy (> 0))) xs
253+ x <- Stream.parse (AP.many (PR.satisfy (> 0))) xs
138254 return $ Prelude.length x
139255
140256{-# INLINE some #-}
141−some :: MonadCatch m => SerialT m Int -> m Int
142−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)
143259
144260{-# INLINE someAlt #-}
145−someAlt :: MonadCatch m => SerialT m Int -> m Int
261+someAlt :: Monad m => Stream m Int -> m Int
146262someAlt xs = do
147− x <- IP.parse (AP.some (PR.satisfy (> 0))) xs
263+ x <- Stream.parse (AP.some (PR.satisfy (> 0))) xs
148264 return $ Prelude.length x
149265
150266{-# INLINE manyTill #-}
151−manyTill :: MonadCatch m => Int -> SerialT m Int -> m Int
267+manyTill :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
152268manyTill value =
153− 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)
154270
155−{-# INLINE splitAp #-}
156−splitAp :: MonadCatch m
157− => Int -> SerialT m Int -> m ((), ())
158−splitAp value =
159− IP.parse
271+{-# INLINE splitAp2 #-}
272+splitAp2 :: Monad m
273+ => Int -> Stream m Int -> m (Either ParseError ((), ()))
274+splitAp2 value =
275+ Stream.parse
160276 ((,)
161− <$> PR.drainWhile (<= (value `div` 2))
162− <*> 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)
163307 )
164308
165309{-# INLINE splitApBefore #-}
166−splitApBefore :: MonadCatch m
167− => Int -> SerialT m Int -> m ()
310+splitApBefore :: Monad m
311+ => Int -> Stream m Int -> m (Either ParseError ())
168312splitApBefore value =
169− IP.parse
170− ( PR.drainWhile (<= (value `div` 2))
171− *> PR.drainWhile (<= value)
313+ Stream.parse
314+ ( PR.dropWhile (<= (value `div` 2))
315+ *> PR.dropWhile (<= value)
172316 )
173317
174318{-# INLINE splitApAfter #-}
175−splitApAfter :: MonadCatch m
176− => Int -> SerialT m Int -> m ()
319+splitApAfter :: Monad m
320+ => Int -> Stream m Int -> m (Either ParseError ())
177321splitApAfter value =
178− IP.parse
179− ( PR.drainWhile (<= (value `div` 2))
180− <* PR.drainWhile (<= value)
322+ Stream.parse
323+ ( PR.dropWhile (<= (value `div` 2))
324+ <* PR.dropWhile (<= value)
181325 )
182326
183−{-# INLINE serialWith #-}
184−serialWith :: MonadCatch m
185− => Int -> SerialT m Int -> m ((), ())
186−serialWith value =
187− IP.parse
188− (PR.serialWith (,)
189− (PR.drainWhile (<= (value `div` 2)))
190− (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))
191335 )
192336
193337{-# INLINE split_ #-}
194−split_ :: MonadCatch m
195− => Int -> SerialT m Int -> m ()
338+split_ :: Monad m
339+ => Int -> Stream m Int -> m (Either ParseError ())
196340split_ value =
197− IP.parse
341+ Stream.parse
198342 (PR.split_
199− (PR.drainWhile (<= (value `div` 2)))
200− (PR.drainWhile (<= value))
343+ (PR.dropWhile (<= (value `div` 2)))
344+ (PR.dropWhile (<= value))
201345 )
202346
203−{-# INLINE sliceSepByP #-}
204−sliceSepByP :: MonadCatch m
205− => Int -> SerialT m Int -> m()
206−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
355+
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+ )
207431
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+{-
208504{-# INLINE teeAllAny #-}
209−teeAllAny :: MonadCatch m
210− => Int -> SerialT m Int -> m ((), ())
505+teeAllAny :: Monad m
506+ => Int -> Stream m Int -> m ((), ())
211507teeAllAny value =
212− IP.parse
508+ Stream.parse
213509 (PR.teeWith (,)
214− (PR.drainWhile (<= value))
215− (PR.drainWhile (<= value))
510+ (PR.dropWhile (<= value))
511+ (PR.dropWhile (<= value))
216512 )
217513
218514{-# INLINE teeFstAllAny #-}
219−teeFstAllAny :: MonadCatch m
220− => Int -> SerialT m Int -> m ((), ())
515+teeFstAllAny :: Monad m
516+ => Int -> Stream m Int -> m ((), ())
221517teeFstAllAny value =
222− IP.parse
518+ Stream.parse
223519 (PR.teeWithFst (,)
224− (PR.drainWhile (<= value))
225− (PR.drainWhile (<= value))
520+ (PR.dropWhile (<= value))
521+ (PR.dropWhile (<= value))
226522 )
227523
228524{-# INLINE shortestAllAny #-}
229−shortestAllAny :: MonadCatch m
230− => Int -> SerialT m Int -> m ()
525+shortestAllAny :: Monad m
526+ => Int -> Stream m Int -> m (Either ParseError ())
231527shortestAllAny value =
232− IP.parse
528+ Stream.parse
233529 (PR.shortest
234− (PR.drainWhile (<= value))
235− (PR.drainWhile (<= value))
530+ (PR.dropWhile (<= value))
531+ (PR.dropWhile (<= value))
236532 )
237533
238534{-# INLINE longestAllAny #-}
239−longestAllAny :: MonadCatch m
240− => Int -> SerialT m Int -> m ()
535+longestAllAny :: Monad m
536+ => Int -> Stream m Int -> m (Either ParseError ())
241537longestAllAny value =
242− IP.parse
538+ Stream.parse
243539 (PR.longest
244− (PR.drainWhile (<= value))
245− (PR.drainWhile (<= value))
540+ (PR.dropWhile (<= value))
541+ (PR.dropWhile (<= value))
246542 )
247−
248−parseManyChunksOfSum :: Int -> Handle -> IO Int
249−parseManyChunksOfSum n inh =
250− S.length
251− $ IP.parseMany
252− (PR.fromFold $ FL.take n FL.sum)
253− (S.unfold Handle.read inh)
543+-}
254544
255545-------------------------------------------------------------------------------
256−-- Parsing with unfolds
546+-- Spanning
257547-------------------------------------------------------------------------------
258548
259−{-# INLINE parseManyUnfoldArrays #-}
260−parseManyUnfoldArrays :: Int -> [Array.Array Int] -> IO ()
261−parseManyUnfoldArrays count arrays = do
262− let src = Source.source (Just (Producer.OuterLoop arrays))
263− let parser = PR.fromFold (FL.take count FL.drain)
264− let readSrc =
265− Source.producer
266− $ Producer.concat Producer.fromList Array.producer
267− let streamParser =
268− Producer.simplify (Source.parseMany parser readSrc)
269− 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)
270569
271570-------------------------------------------------------------------------------
272571-- Parsers in which -fspec-constr-recursive=16 is problematic
@@ -277,63 +576,129 @@ parseManyUnfoldArrays count arrays = do
277576-- not have to rely on it.
278577--
279578{-# INLINE lookAhead #-}
280−lookAhead :: MonadCatch m => Int -> SerialT m Int -> m ()
579+lookAhead :: Monad m => Int -> Stream m Int -> m (Either ParseError ())
281580lookAhead value =
282− IP.parse (PR.lookAhead (PR.takeWhile (<= value) FL.drain) $> ())
581+ Stream.parse (PR.lookAhead (PR.takeWhile (<= value) Fold.drain) $> ())
582+
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)))
283588
589+-- quadratic complexity
284590{-# INLINE sequenceA #-}
285−sequenceA :: MonadCatch m => Int -> SerialT m Int -> m Int
591+sequenceA :: Monad m => Int -> Stream m Int -> m Int
286592sequenceA value xs = do
287− x <- IP.parse (TR.sequenceA (replicate value (PR.satisfy (> 0)))) xs
593+ x <- Stream.parse (TR.sequenceA (replicate value (PR.satisfy (> 0)))) xs
288594 return $ length x
289595
290−{-# INLINE sequenceA_ #-}
291−sequenceA_ :: MonadCatch m => Int -> SerialT m Int -> m ()
292−sequenceA_ value =
293− IP.parse (F.sequenceA_ $ replicate value (PR.satisfy (> 0)))
294−
596+-- quadratic complexity
295597{-# INLINE sequence #-}
296−sequence :: MonadCatch m => Int -> SerialT m Int -> m Int
598+sequence :: Monad m => Int -> Stream m Int -> m Int
297599sequence value xs = do
298− x <- IP.parse (TR.sequence (replicate value (PR.satisfy (> 0)))) xs
600+ x <- Stream.parse (TR.sequence (replicate value (PR.satisfy (> 0)))) xs
299601 return $ length x
300602
301603{-# INLINE sequence_ #-}
302−sequence_ :: MonadCatch m => Int -> SerialT m Int -> m ()
303−sequence_ value =
304− 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
305607
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+--
306616{-# INLINE choiceAsum #-}
307−choiceAsum :: MonadCatch m => Int -> SerialT m Int -> m Int
617+choiceAsum :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
308618choiceAsum value =
309− IP.parse (asum (replicate value (PR.satisfy (< 0)))
619+ Stream.parse (F.asum (replicate value (PR.satisfy (< 0)))
310620 AP.<|> PR.satisfy (> 0))
311621
622+{-
312623{-# INLINE choice #-}
313−choice :: MonadCatch m => Int -> SerialT m Int -> m Int
624+choice :: Monad m => Int -> Stream m Int -> m (Either ParseError Int)
314625choice value =
315− IP.parse
626+ Stream.parse
316627 (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
317645
318646-------------------------------------------------------------------------------
319647-- Stream transformation
320648-------------------------------------------------------------------------------
321649
322650{-# INLINE parseMany #-}
323−parseMany :: MonadCatch m => Int -> SerialT m Int -> m ()
651+parseMany :: Monad m => Int -> Stream m Int -> m ()
324652parseMany n =
325− S.drain
326− . S.map getSum
327− . IP.parseMany (PR.fromFold $ FL.take n FL.mconcat)
328− . 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
329686
330687{-# INLINE parseIterate #-}
331−parseIterate :: MonadCatch m => Int -> SerialT m Int -> m ()
688+parseIterate :: Monad m => Int -> Stream m Int -> m ()
332689parseIterate n =
333− S.drain
334− . S.map getSum
335− . IP.parseIterate (PR.fromFold . FL.take n . FL.sconcat) (Sum 0)
336− . 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
337702
338703-------------------------------------------------------------------------------
339704-- Benchmarks
@@ -342,42 +707,95 @@ parseIterate n =
342707moduleName :: String
343708moduleName = "Data.Parser"
344709
710+instance NFData ParseError where
711+ {-# INLINE rnf #-}
712+ rnf (ParseError x) = rnf x
713+
345714o_1_space_serial :: Int -> [Benchmark]
346715o_1_space_serial value =
347− [ benchIOSink value "next" $ next value
348− , benchIOSink value "takeBetween" $ takeBetween value
349− , benchIOSink value "takeEQ" $ takeEQ value
716+ [ benchIOSink value "takeBetween" $ takeBetween value
350717 , benchIOSink value "takeWhile" $ takeWhile value
718+ , benchIOSink value "takeWhileP" $ takeWhileP value
351719 , benchIOSink value "takeP" $ takeP value
352− , benchIOSink value "drainWhile" $ drainWhile value
353− , benchIOSink value "sliceBeginWith" $ sliceBeginWith value
720+ , benchIOSink value "dropWhile" $ dropWhile value
721+ , benchIOSink value "takeStartBy" $ takeStartBy value
722+ , benchIOSink value "takeEndBy_" $ takeEndBy_ value
354723 , benchIOSink value "groupBy" $ groupBy
355724 , benchIOSink value "groupByRolling" $ groupByRolling
356725 , benchIOSink value "wordBy" $ wordBy value
357− , 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
358736 , benchIOSink value "splitApBefore" $ splitApBefore value
359737 , benchIOSink value "splitApAfter" $ splitApAfter value
360− , benchIOSink value "serialWith" $ serialWith value
361− , 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
362751 , benchIOSink value "many" many
363752 , benchIOSink value "many (wordBy even)" $ manyWordByEven
364753 , benchIOSink value "some" some
365754 , benchIOSink value "manyTill" $ manyTill value
366− , benchIOSink value "tee" $ teeAllAny value
367− , benchIOSink value "teeFst" $ teeFstAllAny value
368− , benchIOSink value "shortest" $ shortestAllAny value
369− , benchIOSink value "longest" $ longestAllAny value
755+ , benchIOSink value "parseMany" $ parseMany value
370756 , benchIOSink value "parseMany (take 1)" (parseMany 1)
371757 , 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
372770 , benchIOSink value "parseIterate (take 1)" (parseIterate 1)
373771 , 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)
374780 ]
375781
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+
376794o_1_space_filesystem :: BenchEnv -> [Benchmark]
377795o_1_space_filesystem env =
378− [ mkBench ("S.parseMany (FL.take " ++ show (bigSize env) ++ " FL.sum)") env
796+ [ mkBench ("S.parseMany (Fold.take " ++ show (bigSize env) ++ " Fold.sum)") env
379797 $ \inh _ -> noinline parseManyChunksOfSum (bigSize env) inh
380− , mkBench "S.parseMany (FL.take 1 FL.sum)" env
798+ , mkBench "S.parseMany (Fold.take 1 Fold.sum)" env
381799 $ \inh _ -> inline parseManyChunksOfSum 1 inh
382800 ]
383801
@@ -392,26 +810,38 @@ o_1_space_serial_unfold bound arrays =
392810o_n_heap_serial :: Int -> [Benchmark]
393811o_n_heap_serial value =
394812 [
813+ benchIOSink value "takeEQ" $ takeEQ value
814+ , benchIOSink value "takeGE" $ takeGE value
815+
395816 -- lookahead benchmark holds the entire input till end
396− benchIOSink value "lookAhead" $ lookAhead value
817+ , benchIOSink value "lookAhead" $ lookAhead value
397818
398− -- accumulates the results in a list
399− , benchIOSink value "sequence" $ sequence value
400− , benchIOSink value "sequenceA" $ sequenceA value
819+ -- o-n-heap because of backtracking
820+ , benchIOSrc sourceEscapedFrames value "takeFramedByEsc_"
821+ $ takeFramedByEsc_ value
401822
402− -- XXX why should this take O(n) heap, it discards the results?
403− , benchIOSink value "sequence_" $ sequence_ value
404− , benchIOSink value "sequenceA_" $ sequenceA_ value
405823 -- non-linear time complexity (parserD)
406824 , benchIOSink value "split_" $ split_ value
407− -- XXX why O(n) heap?
408− , benchIOSink value "choice (asum)" $ choiceAsum value
409− , benchIOSink value "choice" $ choice value
825+ -- XXX Takes lot of space when run on a long stream, why?
826+ , benchIOSink value "monad16" $ monad16 value
410827
411828 -- These show non-linear time complexity.
412829 -- They accumulate the results in a list.
830+ , benchIOSink value "sepBy1" sepBy1
413831 , benchIOSink value "manyAlt" manyAlt
414832 , 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)
415845 ]
416846
417847-------------------------------------------------------------------------------
@@ -420,12 +850,13 @@ o_n_heap_serial value =
420850
421851main :: IO ()
422852main = do
853+#ifndef FUSION_CHECK
423854 env <- mkHandleBenchEnv
424855 runWithCLIOptsEnv defaultStreamSize alloc (allBenchmarks env)
425856
426857 where
427858
428− alloc value = IP.toList $ IP.arraysOf 100 $ sourceUnfoldrM value 0
859+ alloc value = Stream.fold Fold.toList $ Stream.chunksOf 100 $ sourceUnfoldrM value 0
429860
430861 allBenchmarks env arrays value =
431862 [ bgroup (o_1_space_prefix moduleName) (o_1_space_serial value)
@@ -435,4 +866,22 @@ main = do
435866 , bgroup (o_1_space_prefix moduleName)
436867 (o_1_space_serial_unfold value arrays)
437868 , bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
869+ , bgroup (o_n_space_prefix moduleName) (o_n_space_serial value)
438870 ]
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