on master help sign in
Improve performance of parseMany

1. Make the parser state strict so that it can fuse. 2. Use special paths for "Continue 0" and "Done 0" cases Overall improvement from 440 us (6GB allocations) to 175 us (22 MB allocations).

commitc54581ee95e3ab6ac91e3c7c8e11287f00ae3fc7 authorHarendra Kumar <harendra@composewell.com> dateWed 21 Oct 2020, 20:19 (6 years ago) parenta94ec36
1 file changed+11−7
src/Streamly/Internal/Data/Stream/StreamD.hs+11−7
src/Streamly/Internal/Data/Stream/StreamD.hs+11−7
@@ -1029,8 +1029,8 @@ parselMx' pstep initial extract (Stream step state) = do
10291029data ParseChunksState x inpBuf st pst =
10301030 ParseChunksInit inpBuf st
10311031 | ParseChunksInitLeftOver inpBuf
1032− | ParseChunksStream st inpBuf pst
1033− | ParseChunksBuf inpBuf st inpBuf pst
1032+ | ParseChunksStream st inpBuf !pst
1033+ | ParseChunksBuf inpBuf st inpBuf !pst
10341034 | ParseChunksYield x (ParseChunksState x inpBuf st pst)
10351035
10361036{-# INLINE_NORMAL parseMany #-}
@@ -1075,14 +1075,16 @@ parseMany (PRD.Parser pstep initial extract) (Stream step state) =
10751075 let src0 = Prelude.take n (x:buf)
10761076 src = Prelude.reverse src0
10771077 return $ Skip $ ParseChunksBuf src s [] pst1
1078− -- PR.Continue 0 pst1 ->
1079− -- return $ Skip $ ParseChunksStream s (x:buf) pst1
1078+ PR.Continue 0 pst1 ->
1079+ return $ Skip $ ParseChunksStream s (x:buf) pst1
10801080 PR.Continue n pst1 -> do
10811081 assert (n <= length (x:buf)) (return ())
10821082 let (src0, buf1) = splitAt n (x:buf)
10831083 src = Prelude.reverse src0
10841084 return $ Skip $ ParseChunksBuf src s buf1 pst1
1085− -- XXX Specialize for Stop 0 common case?
1085+ PR.Done 0 b -> do
1086+ return $ Skip $
1087+ ParseChunksYield b (ParseChunksInit [] s)
10861088 PR.Done n b -> do
10871089 assert (n <= length (x:buf)) (return ())
10881090 let src = Prelude.reverse (Prelude.take n (x:buf))
@@ -1111,13 +1113,15 @@ parseMany (PRD.Parser pstep initial extract) (Stream step state) =
11111113 let src0 = Prelude.take n (x:buf)
11121114 src = Prelude.reverse src0 ++ xs
11131115 return $ Skip $ ParseChunksBuf src s [] pst1
1114− -- PR.Continue 0 pst1 -> return $ Skip $ ParseChunksBuf xs s (x:buf) pst1
1116+ PR.Continue 0 pst1 ->
1117+ return $ Skip $ ParseChunksBuf xs s (x:buf) pst1
11151118 PR.Continue n pst1 -> do
11161119 assert (n <= length (x:buf)) (return ())
11171120 let (src0, buf1) = splitAt n (x:buf)
11181121 src = Prelude.reverse src0 ++ xs
11191122 return $ Skip $ ParseChunksBuf src s buf1 pst1
1120− -- XXX Specialize for Stop 0 common case?
1123+ PR.Done 0 b ->
1124+ return $ Skip $ ParseChunksYield b (ParseChunksInit xs s)
11211125 PR.Done n b -> do
11221126 assert (n <= length (x:buf)) (return ())
11231127 let src = Prelude.reverse (Prelude.take n (x:buf)) ++ xs