Skip to content

Commit f844212

Browse files
Add space complexity annotations to Parser benchmarks
1 parent f6368ca commit f844212

File tree

2 files changed

+105
-120
lines changed

2 files changed

+105
-120
lines changed

benchmark/Streamly/Benchmark/Data/Parser.hs

Lines changed: 102 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -710,138 +710,119 @@ instance NFData ParseError where
710710
{-# INLINE rnf #-}
711711
rnf (ParseError x) = rnf x
712712

713-
o_1_space_serial :: Int -> [Benchmark]
714-
o_1_space_serial value =
715-
[ benchIOSink value "takeBetween" $ takeBetween value
716-
, benchIOSink value "takeWhile" $ takeWhile value
717-
, benchIOSink value "takeWhileP" $ takeWhileP value
718-
, benchIOSink value "takeP" $ takeP value
719-
, benchIOSink value "dropWhile" $ dropWhile value
720-
, benchIOSink value "takeBeginBy" $ takeBeginBy value
721-
, benchIOSink value "takeEndBy_" $ takeEndBy_ value
722-
, benchIOSink value "groupBy" $ groupBy
723-
, benchIOSink value "groupByRolling" $ groupByRolling
724-
, benchIOSink value "wordBy" $ wordBy value
725-
, benchIOSink value "sepBy (words)" sepByWords
726-
, benchIOSink value "sepByAll (words)" sepByAllWords
727-
, benchIOSink value "sepBy1 (words)" sepByWords1
728-
, benchIOSink value "deintercalate" $ deintercalate value
729-
, benchIOSink value "deintercalate1" $ deintercalate1 value
730-
, benchIOSink value "deintercalateAll" $ deintercalateAll value
713+
benchmarks :: Int -> BenchEnv -> [Array.Array Int] -> [(SpaceComplexity, Benchmark)]
714+
benchmarks value env arrays =
715+
[ (SpaceO_1, benchIOSink value "takeBetween" $ takeBetween value)
716+
, (SpaceO_1, benchIOSink value "takeWhile" $ takeWhile value)
717+
, (SpaceO_1, benchIOSink value "takeWhileP" $ takeWhileP value)
718+
, (SpaceO_1, benchIOSink value "takeP" $ takeP value)
719+
, (SpaceO_1, benchIOSink value "dropWhile" $ dropWhile value)
720+
, (SpaceO_1, benchIOSink value "takeBeginBy" $ takeBeginBy value)
721+
, (SpaceO_1, benchIOSink value "takeEndBy_" $ takeEndBy_ value)
722+
, (SpaceO_1, benchIOSink value "groupBy" $ groupBy)
723+
, (SpaceO_1, benchIOSink value "groupByRolling" $ groupByRolling)
724+
, (SpaceO_1, benchIOSink value "wordBy" $ wordBy value)
725+
, (SpaceO_1, benchIOSink value "sepBy (words)" sepByWords)
726+
, (SpaceO_1, benchIOSink value "sepByAll (words)" sepByAllWords)
727+
, (SpaceO_1, benchIOSink value "sepBy1 (words)" sepByWords1)
728+
, (SpaceO_1, benchIOSink value "deintercalate" $ deintercalate value)
729+
, (SpaceO_1, benchIOSink value "deintercalate1" $ deintercalate1 value)
730+
, (SpaceO_1, benchIOSink value "deintercalateAll" $ deintercalateAll value)
731731
-- Applicative and Monad
732-
, benchIOSink value "splitAp2" $ splitAp2 value
733-
, benchIOSink value "splitAp4" $ splitAp4 value
734-
, benchIOSink value "splitAp8" $ splitAp8 value
735-
, benchIOSink value "splitApBefore" $ splitApBefore value
736-
, benchIOSink value "splitApAfter" $ splitApAfter value
737-
, benchIOSink value "splitWith2" $ splitWith2 value
738-
, benchIOSink value "span" $ span value
739-
, benchIOSink value "spanBy" $ spanBy value
740-
, benchIOSink value "spanByRolling" $ spanByRolling value
741-
, benchIOSink value "monad2" $ monad value
742-
, benchIOSink value "monad4" $ monad4 value
743-
, benchIOSink value "monad8" $ monad8 value
732+
, (SpaceO_1, benchIOSink value "splitAp2" $ splitAp2 value)
733+
, (SpaceO_1, benchIOSink value "splitAp4" $ splitAp4 value)
734+
, (SpaceO_1, benchIOSink value "splitAp8" $ splitAp8 value)
735+
, (SpaceO_1, benchIOSink value "splitApBefore" $ splitApBefore value)
736+
, (SpaceO_1, benchIOSink value "splitApAfter" $ splitApAfter value)
737+
, (SpaceO_1, benchIOSink value "splitWith2" $ splitWith2 value)
738+
, (SpaceO_1, benchIOSink value "span" $ span value)
739+
, (SpaceO_1, benchIOSink value "spanBy" $ spanBy value)
740+
, (SpaceO_1, benchIOSink value "spanByRolling" $ spanByRolling value)
741+
, (SpaceO_1, benchIOSink value "monad2" $ monad value)
742+
, (SpaceO_1, benchIOSink value "monad4" $ monad4 value)
743+
, (SpaceO_1, benchIOSink value "monad8" $ monad8 value)
744744
-- Alternative
745-
, benchIOSink value "alt2parseMany" $ altSmall value
746-
, benchIOSink value "alt2" $ alt2 value
747-
, benchIOSink value "alt4" $ alt4 value
748-
, benchIOSink value "alt8" $ alt8 value
749-
, benchIOSink value "alt16" $ alt16 value
750-
, benchIOSink value "many" many
751-
, benchIOSink value "many (wordBy even)" $ manyWordByEven
752-
, benchIOSink value "some" some
753-
, benchIOSink value "manyTill" $ manyTill value
754-
, benchIOSink value "parseMany" $ parseMany value
755-
, benchIOSink value "parseMany (take 1)" (parseMany 1)
756-
, benchIOSink value "parseMany (take all)" (parseMany value)
757-
, benchIOSink value "parseMany (groupBy (<))" (parseManyGroupBy (<))
758-
, benchIOSink value "parseMany (groupBy (==))" (parseManyGroupBy (==))
759-
, benchIOSink value "parseMany groupRollingBy (bound groups)"
760-
$ parseManyGroupsRolling False
761-
, benchIOSink value "parseMany groupRollingBy (1 group)"
762-
$ parseManyGroupsRolling True
763-
, bench "parseMany groupRollingByEither (Left)"
764-
$ nfIO $ parseManyGroupsRollingEitherLeft
765-
, bench "parseMany groupRollingByEither (Right)"
766-
$ nfIO $ parseManyGroupsRollingEitherRight
767-
, bench "parseMany groupRollingByEither (Alternating)"
768-
$ nfIO $ parseManyGroupsRollingEitherAlt1
769-
, benchIOSink value "parseIterate (take 1)" (parseIterate 1)
770-
, benchIOSink value "parseIterate (take all)" (parseIterate value)
771-
, benchIOSink value "concatSequence" concatSequence
745+
, (SpaceO_1, benchIOSink value "alt2parseMany" $ altSmall value)
746+
, (SpaceO_1, benchIOSink value "alt2" $ alt2 value)
747+
, (SpaceO_1, benchIOSink value "alt4" $ alt4 value)
748+
, (SpaceO_1, benchIOSink value "alt8" $ alt8 value)
749+
, (SpaceO_1, benchIOSink value "alt16" $ alt16 value)
750+
, (SpaceO_1, benchIOSink value "many" many)
751+
, (SpaceO_1, benchIOSink value "many (wordBy even)" $ manyWordByEven)
752+
, (SpaceO_1, benchIOSink value "some" some)
753+
, (SpaceO_1, benchIOSink value "manyTill" $ manyTill value)
754+
, (SpaceO_1, benchIOSink value "parseMany" $ parseMany value)
755+
, (SpaceO_1, benchIOSink value "parseMany (take 1)" (parseMany 1))
756+
, (SpaceO_1, benchIOSink value "parseMany (take all)" (parseMany value))
757+
, (SpaceO_1, benchIOSink value "parseMany (groupBy (<))" (parseManyGroupBy (<)))
758+
, (SpaceO_1, benchIOSink value "parseMany (groupBy (==))" (parseManyGroupBy (==)))
759+
, (SpaceO_1, benchIOSink value "parseMany groupRollingBy (bound groups)"
760+
$ parseManyGroupsRolling False)
761+
, (SpaceO_1, benchIOSink value "parseMany groupRollingBy (1 group)"
762+
$ parseManyGroupsRolling True)
763+
, (SpaceO_1, bench "parseMany groupRollingByEither (Left)"
764+
$ nfIO $ parseManyGroupsRollingEitherLeft)
765+
, (SpaceO_1, bench "parseMany groupRollingByEither (Right)"
766+
$ nfIO $ parseManyGroupsRollingEitherRight)
767+
, (SpaceO_1, bench "parseMany groupRollingByEither (Alternating)"
768+
$ nfIO $ parseManyGroupsRollingEitherAlt1)
769+
, (SpaceO_1, benchIOSink value "parseIterate (take 1)" (parseIterate 1))
770+
, (SpaceO_1, benchIOSink value "parseIterate (take all)" (parseIterate value))
771+
, (SpaceO_1, benchIOSink value "concatSequence" concatSequence)
772772
{-
773773
, benchIOSink value "tee" $ teeAllAny value
774774
, benchIOSink value "teeFst" $ teeFstAllAny value
775775
, benchIOSink value "shortest" $ shortestAllAny value
776776
, benchIOSink value "longest" $ longestAllAny value
777777
-}
778-
, benchIOSink value "streamEqBy" (streamEqBy value)
779-
]
780-
781-
where
782-
783-
{-# NOINLINE parseManyGroupsRollingEitherLeft #-}
784-
parseManyGroupsRollingEitherLeft = parseManyGroupsRollingEither (<) value
785-
786-
{-# NOINLINE parseManyGroupsRollingEitherRight #-}
787-
parseManyGroupsRollingEitherRight = parseManyGroupsRollingEither (>) value
788-
789-
{-# NOINLINE parseManyGroupsRollingEitherAlt1 #-}
790-
parseManyGroupsRollingEitherAlt1 =
791-
parseManyGroupsRollingEitherAlt (>) value
792-
793-
o_1_space_filesystem :: BenchEnv -> [Benchmark]
794-
o_1_space_filesystem env =
795-
[ mkBench ("S.parseMany (Fold.take " ++ show (bigSize env) ++ " Fold.sum)") env
796-
$ \inh _ -> noinline parseManyChunksOfSum (bigSize env) inh
797-
, mkBench "S.parseMany (Fold.take 1 Fold.sum)" env
798-
$ \inh _ -> inline parseManyChunksOfSum 1 inh
799-
]
800-
801-
o_1_space_serial_unfold :: Int -> [Array.Array Int] -> [Benchmark]
802-
o_1_space_serial_unfold bound arrays =
803-
[ bench "parseMany/Unfold/1000 arrays/take all"
804-
$ nfIO $ parseManyUnfoldArrays bound arrays
805-
, bench "parseMany/Unfold/1000 arrays/take 1"
806-
$ nfIO $ parseManyUnfoldArrays 1 arrays
807-
]
808-
809-
o_n_heap_serial :: Int -> [Benchmark]
810-
o_n_heap_serial value =
811-
[
812-
benchIOSink value "takeEQ" $ takeEQ value
813-
, benchIOSink value "takeGE" $ takeGE value
778+
, (SpaceO_1, benchIOSink value "streamEqBy" (streamEqBy value))
779+
, (SpaceO_1, mkBench ("parseMany (Fold.take " ++ show (bigSize env) ++ " Fold.sum)") env
780+
$ \inh _ -> noinline parseManyChunksOfSum (bigSize env) inh)
781+
, (SpaceO_1, mkBench "parseMany (Fold.take 1 Fold.sum)" env
782+
$ \inh _ -> inline parseManyChunksOfSum 1 inh)
783+
, (SpaceO_1, bench "parseMany/Unfold/1000 arrays/take all"
784+
$ nfIO $ parseManyUnfoldArrays value arrays)
785+
, (SpaceO_1, bench "parseMany/Unfold/1000 arrays/take 1"
786+
$ nfIO $ parseManyUnfoldArrays 1 arrays)
787+
, (HeapO_n, benchIOSink value "takeEQ" $ takeEQ value)
788+
, (HeapO_n, benchIOSink value "takeGE" $ takeGE value)
814789

815790
-- lookahead benchmark holds the entire input till end
816-
, benchIOSink value "lookAhead" $ lookAhead value
791+
, (HeapO_n, benchIOSink value "lookAhead" $ lookAhead value)
817792

818793
-- o-n-heap because of backtracking
819-
, benchIOSrc sourceEscapedFrames value "takeFramedByEsc_"
820-
$ takeFramedByEsc_ value
794+
, (HeapO_n, benchIOSrc sourceEscapedFrames value "takeFramedByEsc_"
795+
$ takeFramedByEsc_ value)
821796

822797
-- non-linear time complexity (parserD)
823-
, benchIOSink value "split_" $ split_ value
798+
, (HeapO_n, benchIOSink value "split_" $ split_ value)
824799
-- XXX Takes lot of space when run on a long stream, why?
825-
, benchIOSink value "monad16" $ monad16 value
800+
, (HeapO_n, benchIOSink value "monad16" $ monad16 value)
826801

827802
-- These show non-linear time complexity.
828803
-- They accumulate the results in a list.
829-
, benchIOSink value "sepBy1" sepBy1
830-
, benchIOSink value "manyAlt" manyAlt
831-
, benchIOSink value "someAlt" someAlt
832-
, benchIOSink value "listEqBy" (listEqBy value)
833-
]
834-
835-
-- accumulate results in a list in IO
836-
o_n_space_serial :: Int -> [Benchmark]
837-
o_n_space_serial value =
838-
[ benchIOSink value "sequenceA/100" $ sequenceA (value `div` 100)
839-
, benchIOSink value "sequenceA_/100" $ sequenceA_ (value `div` 100)
840-
, benchIOSink value "sequence/100" $ sequence (value `div` 100)
841-
, benchIOSink value "sequence_/100" $ sequence_ (value `div` 100)
842-
, benchIOSink value "choice (asum)/100" $ choiceAsum (value `div` 100)
804+
, (HeapO_n, benchIOSink value "sepBy1" sepBy1)
805+
, (HeapO_n, benchIOSink value "manyAlt" manyAlt)
806+
, (HeapO_n, benchIOSink value "someAlt" someAlt)
807+
, (HeapO_n, benchIOSink value "listEqBy" (listEqBy value))
808+
, (SpaceO_n, benchIOSink value "sequenceA/100" $ sequenceA (value `div` 100))
809+
, (SpaceO_n, benchIOSink value "sequenceA_/100" $ sequenceA_ (value `div` 100))
810+
, (SpaceO_n, benchIOSink value "sequence/100" $ sequence (value `div` 100))
811+
, (SpaceO_n, benchIOSink value "sequence_/100" $ sequence_ (value `div` 100))
812+
, (SpaceO_n, benchIOSink value "choice (asum)/100" $ choiceAsum (value `div` 100))
843813
-- , benchIOSink value "choice/100" $ choice (value `div` 100)
844814
]
815+
where
816+
817+
{-# NOINLINE parseManyGroupsRollingEitherLeft #-}
818+
parseManyGroupsRollingEitherLeft = parseManyGroupsRollingEither (<) value
819+
820+
{-# NOINLINE parseManyGroupsRollingEitherRight #-}
821+
parseManyGroupsRollingEitherRight = parseManyGroupsRollingEither (>) value
822+
823+
{-# NOINLINE parseManyGroupsRollingEitherAlt1 #-}
824+
parseManyGroupsRollingEitherAlt1 =
825+
parseManyGroupsRollingEitherAlt (>) value
845826

846827
-------------------------------------------------------------------------------
847828
-- Driver
@@ -858,14 +839,15 @@ main = do
858839
alloc value = Stream.fold Fold.toList $ Array.chunksOf 100 $ sourceUnfoldrM value 0
859840

860841
allBenchmarks env arrays value =
861-
[ bgroup (o_1_space_prefix moduleName) (o_1_space_serial value)
862-
, bgroup
863-
(o_1_space_prefix moduleName ++ "/filesystem")
864-
(o_1_space_filesystem env)
865-
, bgroup (o_1_space_prefix moduleName)
866-
(o_1_space_serial_unfold value arrays)
867-
, bgroup (o_n_heap_prefix moduleName) (o_n_heap_serial value)
868-
, bgroup (o_n_space_prefix moduleName) (o_n_space_serial value)
842+
let allBenches = benchmarks value env arrays
843+
get x = map snd $ filter ((==) x . fst) allBenches
844+
o_1_space = get SpaceO_1
845+
o_n_heap = get HeapO_n
846+
o_n_space = get SpaceO_n
847+
in
848+
[ bgroup (o_1_space_prefix moduleName) o_1_space
849+
, bgroup (o_n_heap_prefix moduleName) o_n_heap
850+
, bgroup (o_n_space_prefix moduleName) o_n_space
869851
]
870852
#else
871853
-- Enable FUSION_CHECK macro at the beginning of the file

benchmark/lib/Streamly/Benchmark/Common.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module Streamly.Benchmark.Common
1313
, o_n_space_prefix
1414
, o_n_heap_prefix
1515
, o_n_stack_prefix
16+
, SpaceComplexity(..)
1617

1718
, runWithCLIOptsEnv
1819
, runWithCLIOpts
@@ -62,6 +63,8 @@ import Test.Tasty.Bench
6263
-- Benchmark Prefixes
6364
-------------------------------------------------------------------------------
6465

66+
data SpaceComplexity = SpaceO_1 | HeapO_n | StackO_n | SpaceO_n deriving Eq
67+
6568
o_1_space_prefix :: String -> String
6669
o_1_space_prefix name = name ++ "/o-1-space"
6770

0 commit comments

Comments
 (0)