on master help sign in
Add benchmarks for all types of continuation parsers
commit7f24c4d3526fee49b0a5df487263df57b44496be authorAdithya Kumar <adithya@composewell.com> dateSun 6 Aug 2023, 19:49 (3 years ago) parentf5c33b9
2 files changed+111−33
benchmark/Streamly/Benchmark/Data/ParserK.hs+86−33 benchmark/streamly-benchmarks.cabal+25
benchmark/Streamly/Benchmark/Data/ParserK.hs+86−33
@@ -5,6 +5,10 @@
55-- License : BSD-3-Clause
66-- Maintainer : streamly@composewell.com
77
8+-- BENCH_CHUNKED -> fromParser
9+-- BENCH_CHUNKED_GENERIC -> fromParserGeneric
10+-- BENCH_SINGULAR -> fromParserSingular
11+
812{-# LANGUAGE CPP #-}
913{-# LANGUAGE FlexibleContexts #-}
1014{-# OPTIONS_GHC -Wno-orphans #-}
@@ -18,7 +22,13 @@ import Control.Applicative ((<|>))
1822import Control.DeepSeq (NFData(..))
1923import Control.Monad.IO.Class (MonadIO)
2024import Data.Foldable (asum)
25+#ifdef BENCH_CHUNKED
2126import Streamly.Data.Array (Array, Unbox)
27+#endif
28+#ifdef BENCH_CHUNKED_GENERIC
29+import Streamly.Data.Array.Generic (Array)
30+import qualified Streamly.Internal.Data.Array.Generic as GenArr (chunksOf)
31+#endif
2232import Streamly.Internal.Data.Fold (Fold(..))
2333import Streamly.Data.StreamK (StreamK)
2434import Streamly.Internal.Data.Parser
@@ -35,12 +45,52 @@ import qualified Streamly.Data.Stream as Stream
3545import qualified Streamly.Data.Fold as FL
3646import qualified Streamly.Internal.Data.Fold as Fold
3747import qualified Streamly.Data.Parser as PRD
38−import qualified Streamly.Data.ParserK as PR
48+import qualified Streamly.Internal.Data.Parser.ParserK.Type as PR
3949import qualified Streamly.Internal.Data.StreamK as StreamK
4050
4151import Gauge
4252import Streamly.Benchmark.Common
4353
54+-------------------------------------------------------------------------------
55+-- CPP Helpers
56+-------------------------------------------------------------------------------
57+
58+#ifdef BENCH_CHUNKED
59+
60+#define PARSE_OP StreamK.parseChunks
61+#define FROM_PARSER fromParser
62+#define INPUT (Array a)
63+#define PARSE_ELEM (Array Int)
64+#define CONSTRAINT_IO (MonadIO m, Unbox a)
65+#define CONSTRAINT (Monad m, Unbox a)
66+#define MODULE_NAME "ParserK.Chunked"
67+
68+#endif
69+
70+#ifdef BENCH_CHUNKED_GENERIC
71+
72+#define PARSE_OP StreamK.parseGenericChunks
73+#define FROM_PARSER fromParserGeneric
74+#define INPUT (Array a)
75+#define PARSE_ELEM (Array Int)
76+#define CONSTRAINT_IO (MonadIO m)
77+#define CONSTRAINT (Monad m)
78+#define MODULE_NAME "ParserK.Chunked.Generic"
79+
80+#endif
81+
82+#ifdef BENCH_SINGULAR
83+
84+#define PARSE_OP StreamK.parseSingular
85+#define FROM_PARSER fromParserSingular
86+#define INPUT a
87+#define PARSE_ELEM Int
88+#define CONSTRAINT_IO (MonadIO m)
89+#define CONSTRAINT (Monad m)
90+#define MODULE_NAME "ParserK.Singular"
91+
92+#endif
93+
4494-------------------------------------------------------------------------------
4595-- Utilities
4696-------------------------------------------------------------------------------
@@ -60,49 +110,52 @@ sourceUnfoldrM value n = Stream.unfoldrM step n
60110{-# INLINE benchIOSink #-}
61111benchIOSink
62112 :: NFData b
63− => Int -> String -> (StreamK IO (Array Int) -> IO b) -> Benchmark
113+ => Int -> String -> (StreamK IO PARSE_ELEM -> IO b) -> Benchmark
64114benchIOSink value name f =
65115 bench name $ nfIO $ randomRIO (1,1)
66116 >>= f
67117 . StreamK.fromStream
118+#ifdef BENCH_CHUNKED
68119 . Stream.chunksOf 4000
120+#endif
121+#ifdef BENCH_CHUNKED_GENERIC
122+ . GenArr.chunksOf 4000
123+#endif
69124 . sourceUnfoldrM value
70125
71126-------------------------------------------------------------------------------
72127-- Parsers
73128-------------------------------------------------------------------------------
74129
75−#define PARSE_OP StreamK.parseChunks
76−
77130{-# INLINE one #-}
78131one :: MonadIO m =>
79− Int -> StreamK m (Array Int) -> m (Either ParseError (Maybe Int))
80−one value = StreamK.parseChunks p
132+ Int -> StreamK m PARSE_ELEM -> m (Either ParseError (Maybe Int))
133+one value = PARSE_OP p
81134
82135 where
83136
84137 p = do
85− m <- PR.fromFold FL.one
138+ m <- PR.FROM_PARSER (PRD.fromFold FL.one)
86139 case m of
87140 Just i -> if i >= value then pure m else p
88141 Nothing -> pure Nothing
89142
90143{-# INLINE satisfy #-}
91−satisfy :: (MonadIO m, Unbox a) => (a -> Bool) -> PR.ParserK a m a
92−satisfy = PR.fromParser . PRD.satisfy
144+satisfy :: CONSTRAINT_IO => (a -> Bool) -> PR.ParserK INPUT m a
145+satisfy = PR.FROM_PARSER . PRD.satisfy
93146
94147{-# INLINE takeWhile #-}
95−takeWhile :: (MonadIO m, Unbox a) => (a -> Bool) -> PR.ParserK a m ()
96−takeWhile p = PR.fromParser $ PRD.takeWhile p FL.drain
148+takeWhile :: CONSTRAINT_IO => (a -> Bool) -> PR.ParserK INPUT m ()
149+takeWhile p = PR.FROM_PARSER $ PRD.takeWhile p FL.drain
97150
98151{-# INLINE takeWhileK #-}
99152takeWhileK :: MonadIO m =>
100− Int -> StreamK m (Array Int) -> m (Either ParseError ())
153+ Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
101154takeWhileK value = PARSE_OP (takeWhile (<= value))
102155
103156{-# INLINE splitAp2 #-}
104157splitAp2 :: MonadIO m
105− => Int -> StreamK m (Array Int) -> m (Either ParseError ((), ()))
158+ => Int -> StreamK m PARSE_ELEM -> m (Either ParseError ((), ()))
106159splitAp2 value =
107160 PARSE_OP
108161 ((,)
@@ -112,7 +165,7 @@ splitAp2 value =
112165
113166{-# INLINE splitAp8 #-}
114167splitAp8 :: MonadIO m
115− => Int -> StreamK m (Array Int) -> m (Either ParseError ())
168+ => Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
116169splitAp8 value =
117170 PARSE_OP
118171 ( (\() () () () () () () () -> ())
@@ -127,7 +180,7 @@ splitAp8 value =
127180 )
128181
129182{-# INLINE sequenceA #-}
130−sequenceA :: MonadIO m => Int -> StreamK m (Array Int) -> m Int
183+sequenceA :: MonadIO m => Int -> StreamK m PARSE_ELEM -> m Int
131184sequenceA value xs = do
132185 let parser = satisfy (> 0)
133186 list = Prelude.replicate value parser
@@ -136,14 +189,14 @@ sequenceA value xs = do
136189
137190{-# INLINE sequenceA_ #-}
138191sequenceA_ :: MonadIO m =>
139− Int -> StreamK m (Array Int) -> m (Either ParseError ())
192+ Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
140193sequenceA_ value xs = do
141194 let parser = satisfy (> 0)
142195 list = Prelude.replicate value parser
143196 PARSE_OP (F.sequenceA_ list) xs
144197
145198{-# INLINE sequence #-}
146−sequence :: MonadIO m => Int -> StreamK m (Array Int) -> m Int
199+sequence :: MonadIO m => Int -> StreamK m PARSE_ELEM -> m Int
147200sequence value xs = do
148201 let parser = satisfy (> 0)
149202 list = Prelude.replicate value parser
@@ -152,7 +205,7 @@ sequence value xs = do
152205
153206{-# INLINE sequence_ #-}
154207sequence_ :: MonadIO m =>
155− Int -> StreamK m (Array Int) -> m (Either ParseError ())
208+ Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
156209sequence_ value =
157210 let parser = satisfy (> 0)
158211 list = Prelude.replicate value parser
@@ -184,13 +237,13 @@ takeWhileFailD predicate (Fold fstep finitial fextract) =
184237 extract s = fmap (Done 0) (fextract s)
185238
186239{-# INLINE takeWhileFail #-}
187−takeWhileFail :: (Monad m, Unbox a) =>
188− (a -> Bool) -> Fold m a b -> PR.ParserK a m b
189−takeWhileFail p f = PR.fromParser (takeWhileFailD p f)
240+takeWhileFail :: CONSTRAINT =>
241+ (a -> Bool) -> Fold m a b -> PR.ParserK INPUT m b
242+takeWhileFail p f = PR.FROM_PARSER (takeWhileFailD p f)
190243
191244{-# INLINE alt2 #-}
192245alt2 :: MonadIO m
193− => Int -> StreamK m (Array Int) -> m (Either ParseError ())
246+ => Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
194247alt2 value =
195248 PARSE_OP
196249 ( takeWhileFail (<= (value `div` 2)) Fold.drain
@@ -199,7 +252,7 @@ alt2 value =
199252
200253{-# INLINE alt8 #-}
201254alt8 :: MonadIO m
202− => Int -> StreamK m (Array Int) -> m (Either ParseError ())
255+ => Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
203256alt8 value =
204257 PARSE_OP
205258 ( takeWhileFail (<= ( value `div` 8)) Fold.drain
@@ -214,7 +267,7 @@ alt8 value =
214267
215268{-# INLINE alt16 #-}
216269alt16 :: MonadIO m
217− => Int -> StreamK m (Array Int) -> m (Either ParseError ())
270+ => Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
218271alt16 value =
219272 PARSE_OP
220273 ( takeWhileFail (<= ( value `div` 16)) Fold.drain
@@ -236,27 +289,27 @@ alt16 value =
236289 )
237290
238291{-# INLINE manyAlt #-}
239−manyAlt :: MonadIO m => StreamK m (Array Int) -> m Int
292+manyAlt :: MonadIO m => StreamK m PARSE_ELEM -> m Int
240293manyAlt xs = do
241294 x <- PARSE_OP (AP.many (satisfy (> 0))) xs
242295 return $ Prelude.length x
243296
244297{-# INLINE someAlt #-}
245−someAlt :: MonadIO m => StreamK m (Array Int) -> m Int
298+someAlt :: MonadIO m => StreamK m PARSE_ELEM -> m Int
246299someAlt xs = do
247300 x <- PARSE_OP (AP.some (satisfy (> 0))) xs
248301 return $ Prelude.length x
249302
250303{-# INLINE choice #-}
251304choice :: MonadIO m =>
252− Int -> StreamK m (Array Int) -> m (Either ParseError Int)
305+ Int -> StreamK m PARSE_ELEM -> m (Either ParseError Int)
253306choice value =
254307 PARSE_OP (asum (replicate value (satisfy (< 0)))
255308 AP.<|> satisfy (> 0))
256309
257310{-# INLINE monad2 #-}
258311monad2 :: MonadIO m
259− => Int -> StreamK m (Array Int) -> m (Either ParseError ())
312+ => Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
260313monad2 value =
261314 PARSE_OP $ do
262315 takeWhile (<= (value `div` 2))
@@ -264,7 +317,7 @@ monad2 value =
264317
265318{-# INLINE monad4 #-}
266319monad4 :: MonadIO m
267− => Int -> StreamK m (Array Int) -> m (Either ParseError ())
320+ => Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
268321monad4 value =
269322 PARSE_OP $ do
270323 takeWhile (<= ( value `div` 4))
@@ -274,7 +327,7 @@ monad4 value =
274327
275328{-# INLINE monad8 #-}
276329monad8 :: MonadIO m
277− => Int -> StreamK m (Array Int) -> m (Either ParseError ())
330+ => Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
278331monad8 value =
279332 PARSE_OP $ do
280333 takeWhile (<= ( value `div` 8))
@@ -288,7 +341,7 @@ monad8 value =
288341
289342{-# INLINE monad16 #-}
290343monad16 :: MonadIO m
291− => Int -> StreamK m (Array Int) -> m (Either ParseError ())
344+ => Int -> StreamK m PARSE_ELEM -> m (Either ParseError ())
292345monad16 value =
293346 PARSE_OP $ do
294347 takeWhile (<= ( value `div` 16))
@@ -313,7 +366,7 @@ monad16 value =
313366-------------------------------------------------------------------------------
314367
315368moduleName :: String
316−moduleName = "Data.ParserK"
369+moduleName = MODULE_NAME
317370
318371instance NFData ParseError where
319372 {-# INLINE rnf #-}
@@ -335,7 +388,7 @@ o_1_space_serial value =
335388 ]
336389
337390{-# INLINE sepBy1 #-}
338−sepBy1 :: MonadIO m => StreamK m (Array Int) -> m Int
391+sepBy1 :: MonadIO m => StreamK m PARSE_ELEM -> m Int
339392sepBy1 xs = do
340393 x <- PARSE_OP (parser (satisfy odd) (satisfy even)) xs
341394 return $ Prelude.length x
benchmark/streamly-benchmarks.cabal+25
@@ -415,10 +415,35 @@ benchmark Data.Parser
415415 else
416416 ghc-options: +RTS -M2000M -RTS
417417
418+benchmark Data.ParserK.Singular
419+ import: bench-options
420+ type: exitcode-stdio-1.0
421+ hs-source-dirs: Streamly/Benchmark/Data
422+ cpp-options: -DBENCH_SINGULAR
423+ main-is: ParserK.hs
424+ if impl(ghcjs)
425+ buildable: False
426+ else
427+ buildable: True
428+ build-depends: exceptions >= 0.8 && < 0.11
429+
418430benchmark Data.ParserK
419431 import: bench-options
420432 type: exitcode-stdio-1.0
421433 hs-source-dirs: Streamly/Benchmark/Data
434+ cpp-options: -DBENCH_CHUNKED
435+ main-is: ParserK.hs
436+ if impl(ghcjs)
437+ buildable: False
438+ else
439+ buildable: True
440+ build-depends: exceptions >= 0.8 && < 0.11
441+
442+benchmark Data.ParserK.Generic
443+ import: bench-options
444+ type: exitcode-stdio-1.0
445+ hs-source-dirs: Streamly/Benchmark/Data
446+ cpp-options: -DBENCH_CHUNKED_GENERIC
422447 main-is: ParserK.hs
423448 if impl(ghcjs)
424449 buildable: False