on master help sign in
Combine all the array benchmarks to reduce duplication

Use --stream-size for all the array benchmarks now Replace the following files: - benchmark/Streamly/Benchmark/Data/Array.hs - benchmark/Streamly/Benchmark/Data/ArrayOps.hs - benchmark/Streamly/Benchmark/Data/Prim/Array.hs - benchmark/Streamly/Benchmark/Data/Prim/ArrayOps.hs - benchmark/Streamly/Benchmark/Data/SmallArray.hs - benchmark/Streamly/Benchmark/Data/SmallArrayOps.hs - benchmark/Streamly/Benchmark/Memory/Array.hs - benchmark/Streamly/Benchmark/Memory/ArrayOps.hs With: - benchmark/Streamly/Benchmark/Array.hs - benchmark/Streamly/Benchmark/ArrayOps.hs

commit27c3aebbce2fb38605d14b7ec882a0097893180b authoradithyaov <adi.obilisetty@gmail.com> dateFri 17 Jul 2020, 20:47 (6 years ago) parent26f9f9a
10 files changed+285−1385
benchmark/Streamly/Benchmark/Data/Array.hs+138−55 benchmark/Streamly/Benchmark/Data/ArrayOps.hs+136−43 benchmark/Streamly/Benchmark/Data/Prim/Array.hs−106 benchmark/Streamly/Benchmark/Data/Prim/ArrayOps.hs−153 benchmark/Streamly/Benchmark/Data/SmallArray.hs−101 benchmark/Streamly/Benchmark/Data/SmallArrayOps.hs−136 benchmark/Streamly/Benchmark/Memory/Array.hs−252 benchmark/Streamly/Benchmark/Memory/ArrayOps.hs−531 benchmark/streamly-benchmarks.cabal+11−6 streamly.cabal−2
benchmark/Streamly/Benchmark/Data/Array.hs+138−55
@@ -4,27 +4,43 @@
44--
55-- License : BSD-3-Clause
66-- Maintainer : streamly@composewell.com
7−-- Stability : experimental
8−-- Portability : GHC
97
108{-# LANGUAGE CPP #-}
119
12−module Main (main) where
10+import Control.DeepSeq (NFData(..))
11+
12+#ifndef DATA_PRIM_ARRAY
13+import Control.DeepSeq (deepseq)
14+#endif
1315
14−import Control.DeepSeq (NFData(..), deepseq)
1516import System.Random (randomRIO)
1617
1718import qualified Streamly.Benchmark.Data.ArrayOps as Ops
18−import qualified Streamly.Internal.Data.Array as A
19−import qualified Streamly.Prelude as S
2019
21−import Streamly.Benchmark.Common
20+import Streamly.Benchmark.Common hiding (benchPureSrc)
2221import Gauge
2322
23+#ifdef MEMORY_ARRAY
24+import qualified GHC.Exts as GHC
25+import Foreign.Storable (Storable(..))
26+#endif
27+
28+#ifdef DATA_PRIM_ARRAY
29+import Data.Primitive.Types (Prim(..))
30+#endif
31+
2432-------------------------------------------------------------------------------
2533--
2634-------------------------------------------------------------------------------
2735
36+#ifdef MEMORY_ARRAY
37+-- Drain a source that generates a pure array
38+{-# INLINE benchPureSrc #-}
39+benchPureSrc ::
40+ (NFData a, Storable a) => String -> (Int -> Ops.Stream a) -> Benchmark
41+benchPureSrc name src = benchPure name src id
42+#endif
43+
2844{-# INLINE benchIO #-}
2945benchIO :: NFData b => String -> (Int -> IO a) -> (a -> b) -> Benchmark
3046benchIO name src f = bench name $ nfIO $
@@ -32,13 +48,21 @@ benchIO name src f = bench name $ nfIO $
3248
3349-- Drain a source that generates an array in the IO monad
3450{-# INLINE benchIOSrc #-}
35−benchIOSrc :: (NFData a)
36− => String -> (Int -> IO (Ops.Stream a)) -> Benchmark
51+benchIOSrc ::
52+#ifndef DATA_PRIM_ARRAY
53+ NFData a =>
54+#endif
55+#ifdef MEMORY_ARRAY
56+ Storable a =>
57+#elif defined(DATA_PRIM_ARRAY)
58+ Prim a =>
59+#endif
60+ String -> (Int -> IO (Ops.Stream a)) -> Benchmark
3761benchIOSrc name src = benchIO name src id
3862
3963{-# INLINE benchPureSink #-}
40−benchPureSink :: NFData b => String -> (Ops.Stream Int -> b) -> Benchmark
41−benchPureSink name f = benchIO name Ops.sourceIntFromTo f
64+benchPureSink :: NFData b => Int -> String -> (Ops.Stream Int -> b) -> Benchmark
65+benchPureSink value name f = benchIO name (Ops.sourceIntFromTo value) f
4266
4367{-# INLINE benchIO' #-}
4468benchIO' :: NFData b => String -> (Int -> IO a) -> (a -> IO b) -> Benchmark
@@ -46,57 +70,116 @@ benchIO' name src f = bench name $ nfIO $
4670 randomRIO (1,1) >>= src >>= f
4771
4872{-# INLINE benchIOSink #-}
49−benchIOSink :: NFData b => String -> (Ops.Stream Int -> IO b) -> Benchmark
50−benchIOSink name f = benchIO' name Ops.sourceIntFromTo f
51−
52−testStr :: String
53−testStr = mkListString Ops.value
54−
55−moduleName :: String
56−moduleName = "Data.Array"
73+benchIOSink :: NFData b => Int -> String -> (Ops.Stream Int -> IO b) -> Benchmark
74+benchIOSink value name f = benchIO' name (Ops.sourceIntFromTo value) f
5775
58−o_1_space :: [Benchmark]
59−o_1_space =
60− [ bgroup (o_1_space_prefix moduleName)
61− [ bgroup "generation"
62− [ benchIOSrc "writeN . intFromTo" Ops.sourceIntFromTo
63− , benchIOSrc "write . intFromTo" Ops.sourceIntFromToFromStream
64− , benchIOSrc "fromList . intFromTo" Ops.sourceIntFromToFromList
65− , benchIOSrc "writeN . unfoldr" Ops.sourceUnfoldr
66− , benchIOSrc "writeN . fromList" Ops.sourceFromList
67− -- , benchPureSrc "writeN . IsList.fromList" Ops.sourceIsList
68− -- , benchPureSrc "writeN . IsString.fromString" Ops.sourceIsString
69− , testStr `deepseq` (bench "read" $ nf Ops.readInstance testStr)
70− , benchPureSink "show" Ops.showInstance
76+o_1_space_generation :: Int -> [Benchmark]
77+o_1_space_generation value =
78+ [ bgroup
79+ "generation"
80+ [ benchIOSrc "writeN . intFromTo" (Ops.sourceIntFromTo value)
81+#ifndef DATA_SMALLARRAY
82+ , benchIOSrc "write . intFromTo" (Ops.sourceIntFromToFromStream value)
83+#endif
84+ , benchIOSrc
85+ "fromList . intFromTo"
86+ (Ops.sourceIntFromToFromList value)
87+ , benchIOSrc "writeN . unfoldr" (Ops.sourceUnfoldr value)
88+ , benchIOSrc "writeN . fromList" (Ops.sourceFromList value)
89+#ifdef MEMORY_ARRAY
90+ , benchPureSrc "writeN . IsList.fromList" (Ops.sourceIsList value)
91+ , benchPureSrc
92+ "writeN . IsString.fromString"
93+ (Ops.sourceIsString value)
94+#endif
95+#ifndef DATA_PRIM_ARRAY
96+#ifdef DATA_SMALLARRAY
97+ , let testStr =
98+ "fromListN " ++
99+ show (value + 1) ++
100+ "[1" ++ concat (replicate value ",1") ++ "]"
101+#else
102+ , let testStr = mkListString value
103+#endif
104+ in testStr `deepseq` (bench "read" $ nf Ops.readInstance testStr)
105+#endif
106+ , benchPureSink value "show" Ops.showInstance
71107 ]
72− , bgroup "elimination"
73− [ benchPureSink "id" id
74− , benchPureSink "==" Ops.eqInstance
75− , benchPureSink "/=" Ops.eqInstanceNotEq
76− , benchPureSink "<" Ops.ordInstance
77− , benchPureSink "min" Ops.ordInstanceMin
108+ ]
109+
110+o_1_space_elimination :: Int -> [Benchmark]
111+o_1_space_elimination value =
112+ [ bgroup "elimination"
113+ [ benchPureSink value "id" id
114+ , benchPureSink value "==" Ops.eqInstance
115+ , benchPureSink value "/=" Ops.eqInstanceNotEq
116+ , benchPureSink value "<" Ops.ordInstance
117+ , benchPureSink value "min" Ops.ordInstanceMin
118+#ifdef MEMORY_ARRAY
78119 -- length is used to check for foldr/build fusion
79− -- , benchPureSink "length . IsList.toList" (length . GHC.toList)
80− , benchIOSink "foldl'" Ops.pureFoldl'
81− , benchIOSink "read" (S.drain . S.unfold A.read)
82− , benchIOSink "toStreamRev" (S.drain . A.toStreamRev)
120+ , benchPureSink value "length . IsList.toList" (length . GHC.toList)
121+#endif
122+ , benchIOSink value "foldl'" Ops.pureFoldl'
123+ , benchIOSink value "read" Ops.unfoldReadDrain
124+ , benchIOSink value "toStreamRev" Ops.toStreamRevDrain
125+#ifndef DATA_PRIM_ARRAY
83126#ifdef DEVBUILD
84− , benchPureSink "foldable/foldl'" Ops.foldableFoldl'
85− , benchPureSink "foldable/sum" Ops.foldableSum
127+ , benchPureSink value "foldable/foldl'" Ops.foldableFoldl'
128+ , benchPureSink value "foldable/sum" Ops.foldableSum
129+#endif
86130#endif
87131 ]
88− , bgroup "transformation"
89− [ benchIOSink "scanl'" (Ops.scanl' 1)
90− , benchIOSink "scanl1'" (Ops.scanl1' 1)
91− , benchIOSink "map" (Ops.map 1)
132+ ]
133+
134+o_1_space_transformation :: Int -> [Benchmark]
135+o_1_space_transformation value =
136+ [ bgroup "transformation"
137+ [ benchIOSink value "scanl'" (Ops.scanl' value 1)
138+ , benchIOSink value "scanl1'" (Ops.scanl1' value 1)
139+ , benchIOSink value "map" (Ops.map value 1)
92140 ]
93− , bgroup "transformationX4"
94− [ benchIOSink "scanl'" (Ops.scanl' 4)
95− , benchIOSink "scanl1'" (Ops.scanl1' 4)
96− , benchIOSink "map" (Ops.map 4)
141+ ]
142+
143+o_1_space_transformationX4 :: Int -> [Benchmark]
144+o_1_space_transformationX4 value =
145+ [ bgroup "transformationX4"
146+ [ benchIOSink value "scanl'" (Ops.scanl' value 4)
147+ , benchIOSink value "scanl1'" (Ops.scanl1' value 4)
148+ , benchIOSink value "map" (Ops.map value 4)
97149 ]
98− ]
99− ]
150+ ]
151+
152+moduleName :: String
153+#ifdef DATA_SMALLARRAY
154+moduleName = "Data.SmallArray"
155+#elif defined(MEMORY_ARRAY)
156+moduleName = "Memory.Array"
157+#elif defined(DATA_PRIM_ARRAY)
158+moduleName = "Data.Prim.Array"
159+#else
160+moduleName = "Data.Array"
161+#endif
162+
163+#ifdef DATA_SMALLARRAY
164+defStreamSize :: Int
165+defStreamSize = 128
166+#else
167+defStreamSize :: Int
168+defStreamSize = defaultStreamSize
169+#endif
100170
101171main :: IO ()
102−main = defaultMain $ concat [o_1_space]
172+main = do
173+ (value, cfg, benches) <- parseCLIOpts defStreamSize
174+ value `seq` runMode (mode cfg) cfg benches (allBenchmarks value)
175+
176+ where
177+
178+ allBenchmarks size =
179+ [ bgroup (o_1_space_prefix moduleName) $ concat
180+ [ o_1_space_generation size
181+ , o_1_space_elimination size
182+ , o_1_space_transformation size
183+ , o_1_space_transformationX4 size
184+ ]
185+ ]
benchmark/Streamly/Benchmark/Data/ArrayOps.hs+136−43
@@ -1,33 +1,56 @@
11-- |
22-- Module : Streamly.Benchmark.Data.ArrayOps
3−-- Copyright : (c) 2019 Composewell Technologies
3+-- Copyright : (c) 2020 Composewell Technologies
44--
55-- License : BSD-3-Clause
66-- Maintainer : streamly@composewell.com
7−-- Stability : experimental
8−-- Portability : GHC
97
10−{-# LANGUAGE CPP #-}
11−{-# LANGUAGE DeriveAnyClass #-}
12−{-# LANGUAGE DeriveGeneric #-}
13−{-# LANGUAGE FlexibleContexts #-}
8+{-# LANGUAGE CPP #-}
9+{-# LANGUAGE FlexibleContexts #-}
1410{-# LANGUAGE ScopedTypeVariables #-}
11+{-# LANGUAGE DeriveAnyClass #-}
12+{-# LANGUAGE DeriveGeneric #-}
13+
14+-- CPP:
15+-- MEMORY_ARRAY
16+-- DATA_ARRAY
17+-- DATA_PRIM_ARRAY
18+-- DATA_SMALLARRAY
1519
1620module Streamly.Benchmark.Data.ArrayOps where
1721
1822import Control.Monad.IO.Class (MonadIO)
19−import Prelude (Int, Bool, (+), ($), (==), (>), (.), Maybe(..), undefined)
23+import Prelude (Bool, Int, Maybe(..), ($), (+), (.), (==), (>), undefined)
24+
2025import qualified Prelude as P
26+import qualified Streamly as S hiding (foldMapWith, runStream)
27+import qualified Streamly.Prelude as S
28+
29+
30+#ifndef DATA_PRIM_ARRAY
2131#ifdef DEVBUILD
2232import qualified Data.Foldable as F
2333#endif
34+#endif
2435
25−import qualified Streamly as S hiding (foldMapWith, runStream)
26−import qualified Streamly.Internal.Data.Array as A
27−import qualified Streamly.Prelude as S
36+#ifdef MEMORY_ARRAY
37+import qualified GHC.Exts as GHC
38+#endif
2839
29−value :: Int
30−value = 100000
40+#ifdef DATA_SMALLARRAY
41+import qualified Streamly.Internal.Data.SmallArray as A
42+type Stream = A.SmallArray
43+#elif defined(MEMORY_ARRAY)
44+import qualified Streamly.Memory.Array as A
45+import qualified Streamly.Internal.Memory.Array as A
46+type Stream = A.Array
47+#elif defined(DATA_PRIM_ARRAY)
48+import qualified Streamly.Internal.Data.Prim.Array as A
49+type Stream = A.PrimArray
50+#else
51+import qualified Streamly.Internal.Data.Array as A
52+type Stream = A.Array
53+#endif
3154
3255-------------------------------------------------------------------------------
3356-- Benchmark ops
@@ -37,11 +60,17 @@ value = 100000
3760-- Stream generation and elimination
3861-------------------------------------------------------------------------------
3962
40−type Stream = A.Array
63+-------------------------------------------------------------------------------
64+-- CPP Common to:
65+-- MEMORY_ARRAY
66+-- DATA_ARRAY
67+-- DATA_PRIM_ARRAY
68+-- DATA_SMALLARRAY
69+-------------------------------------------------------------------------------
4170
4271{-# INLINE sourceUnfoldr #-}
43−sourceUnfoldr :: MonadIO m => Int -> m (Stream Int)
44−sourceUnfoldr n = S.fold (A.writeN value) $ S.unfoldr step n
72+sourceUnfoldr :: MonadIO m => Int -> Int -> m (Stream Int)
73+sourceUnfoldr value n = S.fold (A.writeN value) $ S.unfoldr step n
4574 where
4675 step cnt =
4776 if cnt > n + value
@@ -49,33 +78,65 @@ sourceUnfoldr n = S.fold (A.writeN value) $ S.unfoldr step n
4978 else (Just (cnt, cnt + 1))
5079
5180{-# INLINE sourceIntFromTo #-}
52−sourceIntFromTo :: MonadIO m => Int -> m (Stream Int)
53−sourceIntFromTo n = S.fold (A.writeN value) $ S.enumerateFromTo n (n + value)
81+sourceIntFromTo :: MonadIO m => Int -> Int -> m (Stream Int)
82+sourceIntFromTo value n = S.fold (A.writeN value) $ S.enumerateFromTo n (n + value)
5483
55−{-# INLINE sourceIntFromToFromStream #-}
56−sourceIntFromToFromStream :: MonadIO m => Int -> m (Stream Int)
57−sourceIntFromToFromStream n = S.fold A.write $ S.enumerateFromTo n (n + value)
84+{-# INLINE sourceFromList #-}
85+sourceFromList :: MonadIO m => Int -> Int -> m (Stream Int)
86+sourceFromList value n = S.fold (A.writeN value) $ S.fromList [n..n+value]
5887
88+-- Different defination of sourceIntFromToFromList for DATA_SMALLARRAY
89+-- CPP:
5990{-# INLINE sourceIntFromToFromList #-}
60−sourceIntFromToFromList :: MonadIO m => Int -> m (Stream Int)
61−sourceIntFromToFromList n = P.return $ A.fromList $ [n..n + value]
91+sourceIntFromToFromList :: MonadIO m => Int -> Int -> m (Stream Int)
92+#ifndef DATA_SMALLARRAY
93+sourceIntFromToFromList value n = P.return $ A.fromList $ [n..n + value]
94+#else
95+sourceIntFromToFromList value n = P.return $ A.fromListN value $ [n..n + value]
96+#endif
6297
63−{-# INLINE sourceFromList #-}
64−sourceFromList :: MonadIO m => Int -> m (Stream Int)
65−sourceFromList n = S.fold (A.writeN value) $ S.fromList [n..n+value]
66−{-
98+-------------------------------------------------------------------------------
99+-- CPP Common to:
100+-- MEMORY_ARRAY
101+-- DATA_ARRAY
102+-- DATA_PRIM_ARRAY
103+-------------------------------------------------------------------------------
104+
105+-- CPP:
106+#ifndef DATA_SMALLARRAY
107+{-# INLINE sourceIntFromToFromStream #-}
108+sourceIntFromToFromStream :: MonadIO m => Int -> Int -> m (Stream Int)
109+sourceIntFromToFromStream value n = S.fold A.write $ S.enumerateFromTo n (n + value)
110+#endif
111+
112+-------------------------------------------------------------------------------
113+-- CPP Common to:
114+-- MEMORY_ARRAY
115+-------------------------------------------------------------------------------
116+
117+-- CPP:
118+#ifdef MEMORY_ARRAY
67119{-# INLINE sourceIsList #-}
68−sourceIsList :: Int -> Stream Int
69−sourceIsList n = GHC.fromList [n..n+value]
120+sourceIsList :: Int -> Int -> Stream Int
121+sourceIsList value n = GHC.fromList [n..n+value]
70122
71123{-# INLINE sourceIsString #-}
72−sourceIsString :: Int -> Stream P.Char
73−sourceIsString n = GHC.fromString (P.replicate (n + value) 'a')
74−-}
124+sourceIsString :: Int -> Int -> Stream P.Char
125+sourceIsString value n = GHC.fromString (P.replicate (n + value) 'a')
126+#endif
127+
75128-------------------------------------------------------------------------------
76129-- Transformation
77130-------------------------------------------------------------------------------
78131
132+-------------------------------------------------------------------------------
133+-- CPP Common to:
134+-- MEMORY_ARRAY
135+-- DATA_ARRAY
136+-- DATA_PRIM_ARRAY
137+-- DATA_SMALLARRAY
138+-------------------------------------------------------------------------------
139+
79140{-# INLINE composeN #-}
80141composeN :: P.Monad m
81142 => Int -> (Stream Int -> m (Stream Int)) -> Stream Int -> m (Stream Int)
@@ -91,19 +152,21 @@ composeN n f x =
91152{-# INLINE scanl1' #-}
92153{-# INLINE map #-}
93154
94−scanl', scanl1', map
95− :: MonadIO m => Int -> Stream Int -> m (Stream Int)
155+scanl' , scanl1', map
156+ :: MonadIO m => Int -> Int -> Stream Int -> m (Stream Int)
157+
96158
97159{-# INLINE onArray #-}
98160onArray
99− :: MonadIO m => (S.SerialT m Int -> S.SerialT m Int)
161+ :: MonadIO m => Int -> (S.SerialT m Int -> S.SerialT m Int)
100162 -> Stream Int
101163 -> m (Stream Int)
102−onArray f arr = S.fold (A.writeN value) $ f $ (S.unfold A.read arr)
164+onArray value f arr = S.fold (A.writeN value) $ f $ (S.unfold A.read arr)
103165
104−scanl' n = composeN n $ onArray $ S.scanl' (+) 0
105−scanl1' n = composeN n $ onArray $ S.scanl1' (+)
106−map n = composeN n $ onArray $ S.map (+1)
166+scanl' value n = composeN n $ onArray value $ S.scanl' (+) 0
167+scanl1' value n = composeN n $ onArray value $ S.scanl1' (+)
168+map value n = composeN n $ onArray value $ S.map (+1)
169+-- map n = composeN n $ A.map (+1)
107170
108171{-# INLINE eqInstance #-}
109172eqInstance :: Stream Int -> Bool
@@ -125,6 +188,19 @@ ordInstanceMin src = P.min src src
125188showInstance :: Stream Int -> P.String
126189showInstance src = P.show src
127190
191+{-# INLINE pureFoldl' #-}
192+pureFoldl' :: MonadIO m => Stream Int -> m Int
193+pureFoldl' = S.foldl' (+) 0 . S.unfold A.read
194+
195+-------------------------------------------------------------------------------
196+-- CPP Common to:
197+-- MEMORY_ARRAY
198+-- DATA_ARRAY
199+-- DATA_SMALLARRAY
200+-------------------------------------------------------------------------------
201+
202+-- CPP:
203+#ifndef DATA_PRIM_ARRAY
128204{-# INLINE readInstance #-}
129205readInstance :: P.String -> Stream Int
130206readInstance str =
@@ -133,10 +209,6 @@ readInstance str =
133209 [(x,"")] -> x
134210 _ -> P.error "readInstance: no parse"
135211
136−{-# INLINE pureFoldl' #-}
137−pureFoldl' :: MonadIO m => Stream Int -> m Int
138−pureFoldl' = S.foldl' (+) 0 . S.unfold A.read
139−
140212#ifdef DEVBUILD
141213{-# INLINE foldableFoldl' #-}
142214foldableFoldl' :: Stream Int -> Int
@@ -146,3 +218,24 @@ foldableFoldl' = F.foldl' (+) 0
146218foldableSum :: Stream Int -> Int
147219foldableSum = P.sum
148220#endif
221+#endif
222+
223+-------------------------------------------------------------------------------
224+-- Elimination
225+-------------------------------------------------------------------------------
226+
227+-------------------------------------------------------------------------------
228+-- CPP Common to:
229+-- MEMORY_ARRAY
230+-- DATA_ARRAY
231+-- DATA_PRIM_ARRAY
232+-- DATA_SMALLARRAY
233+-------------------------------------------------------------------------------
234+
235+{-# INLINE unfoldReadDrain #-}
236+unfoldReadDrain :: MonadIO m => Stream Int -> m ()
237+unfoldReadDrain = S.drain . S.unfold A.read
238+
239+{-# INLINE toStreamRevDrain #-}
240+toStreamRevDrain :: MonadIO m => Stream Int -> m ()
241+toStreamRevDrain = S.drain . A.toStreamRev
benchmark/Streamly/Benchmark/Data/Prim/Array.hsdeleted−106
@@ -1,106 +0,0 @@
1−-- |
2−-- Module : Main
3−-- Copyright : (c) 2019 Composewell Technologies
4−--
5−-- License : BSD-3-Clause
6−-- Maintainer : streamly@composewell.com
7−-- Stability : experimental
8−-- Portability : GHC
9−
10−{-# LANGUAGE CPP #-}
11−
12−module Main (main) where
13−
14−import Control.DeepSeq (NFData(..))
15−import System.Random (randomRIO)
16−
17−import qualified Streamly.Benchmark.Data.Prim.ArrayOps as Ops
18−import qualified Streamly.Internal.Data.Prim.Array as A
19−import qualified Streamly.Prelude as S
20−
21−import Streamly.Benchmark.Common
22−import Gauge
23−
24−-------------------------------------------------------------------------------
25−--
26−-------------------------------------------------------------------------------
27−
28−{-# INLINE benchIO #-}
29−benchIO :: NFData b => String -> (Int -> IO a) -> (a -> b) -> Benchmark
30−benchIO name src f = bench name $ nfIO $
31− randomRIO (1,1) >>= src >>= return . f
32−
33−-- Drain a source that generates an array in the IO monad
34−{-# INLINE benchIOSrc #-}
35−benchIOSrc :: A.Prim a => String -> (Int -> IO (Ops.Stream a)) -> Benchmark
36−benchIOSrc name src = benchIO name src id
37−
38−{-# INLINE benchPureSink #-}
39−benchPureSink :: NFData b => String -> (Ops.Stream Int -> b) -> Benchmark
40−benchPureSink name f = benchIO name Ops.sourceIntFromTo f
41−
42−{-# INLINE benchIO' #-}
43−benchIO' :: NFData b => String -> (Int -> IO a) -> (a -> IO b) -> Benchmark
44−benchIO' name src f = bench name $ nfIO $
45− randomRIO (1,1) >>= src >>= f
46−
47−{-# INLINE benchIOSink #-}
48−benchIOSink :: NFData b => String -> (Ops.Stream Int -> IO b) -> Benchmark
49−benchIOSink name f = benchIO' name Ops.sourceIntFromTo f
50−
51−{-
52−testStr :: String
53−testStr = mkListString Ops.value
54−-}
55−
56−moduleName :: String
57−moduleName = "Data.Prim.Array"
58−
59−o_1_space :: [Benchmark]
60−o_1_space =
61− [ bgroup (o_1_space_prefix moduleName)
62− [ bgroup "generation"
63− [ benchIOSrc "writeN . intFromTo" Ops.sourceIntFromTo
64− , benchIOSrc "write . intFromTo" Ops.sourceIntFromToFromStream
65− , benchIOSrc "fromList . intFromTo" Ops.sourceIntFromToFromList
66− , benchIOSrc "writeN . unfoldr" Ops.sourceUnfoldr
67− , benchIOSrc "writeN . fromList" Ops.sourceFromList
68− -- , benchPureSrc "writeN . IsList.fromList" Ops.sourceIsList
69− -- , benchPureSrc "writeN . IsString.fromString" Ops.sourceIsString
70− -- , testStr `deepseq` (bench "read" $ nf Ops.readInstance testStr)
71− , benchPureSink "show" Ops.showInstance
72− ]
73− , bgroup "elimination"
74− [ benchPureSink "id" id
75− , benchPureSink "==" Ops.eqInstance
76− , benchPureSink "/=" Ops.eqInstanceNotEq
77− , benchPureSink "<" Ops.ordInstance
78− , benchPureSink "min" Ops.ordInstanceMin
79− -- length is used to check for foldr/build fusion
80− -- , benchPureSink "length . IsList.toList" (length . GHC.toList)
81− , benchIOSink "foldl'" Ops.pureFoldl'
82− , benchIOSink "read" (S.drain . S.unfold A.read)
83− , benchIOSink "toStreamRev" (S.drain . A.toStreamRev)
84−#if 0
85− -- PrimArray does not have a Foldable instance because it requires a
86− -- Prim constraint. Though it should be possible to make an instance in
87− -- the same way as we do in Memory.Array.
88− , benchPureSink "foldable/foldl'" Ops.foldableFoldl'
89− , benchPureSink "foldable/sum" Ops.foldableSum
90−#endif
91− ]
92− , bgroup "transformation"
93− [ benchIOSink "scanl'" (Ops.scanl' 1)
94− , benchIOSink "scanl1'" (Ops.scanl1' 1)
95− , benchIOSink "map" (Ops.map 1)
96− ]
97− , bgroup "transformationX4"
98− [ benchIOSink "scanl'" (Ops.scanl' 4)
99− , benchIOSink "scanl1'" (Ops.scanl1' 4)
100− , benchIOSink "map" (Ops.map 4)
101− ]
102− ]
103− ]
104−
105−main :: IO ()
106−main = defaultMain $ concat [o_1_space]
benchmark/Streamly/Benchmark/Data/Prim/ArrayOps.hsdeleted−153
@@ -1,153 +0,0 @@
1−-- |
2−-- Module : Streamly.Benchmark.Data.Prim.ArrayOps
3−-- Copyright : (c) 2019 Composewell Technologies
4−--
5−-- License : BSD-3-Clause
6−-- Maintainer : streamly@composewell.com
7−-- Stability : experimental
8−-- Portability : GHC
9−
10−{-# LANGUAGE CPP #-}
11−{-# LANGUAGE DeriveAnyClass #-}
12−{-# LANGUAGE DeriveGeneric #-}
13−{-# LANGUAGE FlexibleContexts #-}
14−{-# LANGUAGE ScopedTypeVariables #-}
15−
16−module Streamly.Benchmark.Data.Prim.ArrayOps where
17−
18−import Control.Monad.IO.Class (MonadIO)
19−import Prelude (Int, Bool, (+), ($), (==), (>), (.), Maybe(..), undefined)
20−import qualified Prelude as P
21−#ifdef DEVBUILD
22−-- import qualified Data.Foldable as F
23−#endif
24−
25−import qualified Streamly as S hiding (foldMapWith, runStream)
26−import qualified Streamly.Internal.Data.Prim.Array as A
27−import qualified Streamly.Prelude as S
28−
29−value :: Int
30−value = 100000
31−
32−-------------------------------------------------------------------------------
33−-- Benchmark ops
34−-------------------------------------------------------------------------------
35−
36−-------------------------------------------------------------------------------
37−-- Stream generation and elimination
38−-------------------------------------------------------------------------------
39−
40−type Stream = A.PrimArray
41−
42−{-# INLINE sourceUnfoldr #-}
43−sourceUnfoldr :: MonadIO m => Int -> m (Stream Int)
44−sourceUnfoldr n = S.fold (A.writeN value) $ S.unfoldr step n
45− where
46− step cnt =
47− if cnt > n + value
48− then Nothing
49− else (Just (cnt, cnt + 1))
50−
51−{-# INLINE sourceIntFromTo #-}
52−sourceIntFromTo :: MonadIO m => Int -> m (Stream Int)
53−sourceIntFromTo n = S.fold (A.writeN value) $ S.enumerateFromTo n (n + value)
54−
55−{-# INLINE sourceIntFromToFromStream #-}
56−sourceIntFromToFromStream :: MonadIO m => Int -> m (Stream Int)
57−sourceIntFromToFromStream n = S.fold A.write $ S.enumerateFromTo n (n + value)
58−
59−{-# INLINE sourceIntFromToFromList #-}
60−sourceIntFromToFromList :: MonadIO m => Int -> m (Stream Int)
61−sourceIntFromToFromList n = P.return $ A.fromList $ [n..n + value]
62−
63−{-# INLINE sourceFromList #-}
64−sourceFromList :: MonadIO m => Int -> m (Stream Int)
65−sourceFromList n = S.fold (A.writeN value) $ S.fromList [n..n+value]
66−{-
67−{-# INLINE sourceIsList #-}
68−sourceIsList :: Int -> Stream Int
69−sourceIsList n = GHC.fromList [n..n+value]
70−
71−{-# INLINE sourceIsString #-}
72−sourceIsString :: Int -> Stream P.Char
73−sourceIsString n = GHC.fromString (P.replicate (n + value) 'a')
74−-}
75−-------------------------------------------------------------------------------
76−-- Transformation
77−-------------------------------------------------------------------------------
78−
79−{-# INLINE composeN #-}
80−composeN :: P.Monad m
81− => Int -> (Stream Int -> m (Stream Int)) -> Stream Int -> m (Stream Int)
82−composeN n f x =
83− case n of
84− 1 -> f x
85− 2 -> f x P.>>= f
86− 3 -> f x P.>>= f P.>>= f
87− 4 -> f x P.>>= f P.>>= f P.>>= f
88− _ -> undefined
89−
90−{-# INLINE scanl' #-}
91−{-# INLINE scanl1' #-}
92−{-# INLINE map #-}
93−
94−scanl', scanl1', map
95− :: MonadIO m => Int -> Stream Int -> m (Stream Int)
96−
97−{-# INLINE onArray #-}
98−onArray
99− :: MonadIO m => (S.SerialT m Int -> S.SerialT m Int)
100− -> Stream Int
101− -> m (Stream Int)
102−onArray f arr = S.fold (A.writeN value) $ f $ (S.unfold A.read arr)
103−
104−scanl' n = composeN n $ onArray $ S.scanl' (+) 0
105−scanl1' n = composeN n $ onArray $ S.scanl1' (+)
106−map n = composeN n $ onArray $ S.map (+1)
107−
108−{-# INLINE eqInstance #-}
109−eqInstance :: Stream Int -> Bool
110−eqInstance src = src == src
111−
112−{-# INLINE eqInstanceNotEq #-}
113−eqInstanceNotEq :: Stream Int -> Bool
114−eqInstanceNotEq src = src P./= src
115−
116−{-# INLINE ordInstance #-}
117−ordInstance :: Stream Int -> Bool
118−ordInstance src = src P.< src
119−
120−{-# INLINE ordInstanceMin #-}
121−ordInstanceMin :: Stream Int -> Stream Int
122−ordInstanceMin src = P.min src src
123−
124−{-# INLINE showInstance #-}
125−showInstance :: Stream Int -> P.String
126−showInstance src = P.show src
127−
128−{-
129−{-# INLINE readInstance #-}
130−readInstance :: P.String -> Stream Int
131−readInstance str =
132− let r = P.reads str
133− in case r of
134− [(x,"")] -> x
135− _ -> P.error "readInstance: no parse"
136−-}
137−
138−{-# INLINE pureFoldl' #-}
139−pureFoldl' :: MonadIO m => Stream Int -> m Int
140−pureFoldl' = S.foldl' (+) 0 . S.unfold A.read
141−
142−#if 0
143−-- PrimArray does not have a Foldable instance because it reuqires a Prim
144−-- constraint. Though it should be possible to make an instance in the same way
145−-- as we do in Memory.Array.
146−{-# INLINE foldableFoldl' #-}
147−foldableFoldl' :: Stream Int -> Int
148−foldableFoldl' = F.foldl' (+) 0
149−
150−{-# INLINE foldableSum #-}
151−foldableSum :: Stream Int -> Int
152−foldableSum = P.sum
153−#endif
benchmark/Streamly/Benchmark/Data/SmallArray.hsdeleted−101
@@ -1,101 +0,0 @@
1−-- |
2−-- Module : Main
3−-- Copyright : (c) 2019 Composewell Technologies
4−--
5−-- License : BSD-3-Clause
6−-- Maintainer : streamly@composewell.com
7−-- Stability : experimental
8−-- Portability : GHC
9−
10−{-# LANGUAGE CPP #-}
11−
12−module Main (main) where
13−
14−import Control.DeepSeq (NFData(..), deepseq)
15−import System.Random (randomRIO)
16−
17−import qualified Streamly.Benchmark.Data.SmallArrayOps as Ops
18−import qualified Streamly.Internal.Data.SmallArray as A
19−import qualified Streamly.Prelude as S
20−
21−import Streamly.Benchmark.Common hiding (mkString)
22−import Gauge
23−
24−-------------------------------------------------------------------------------
25−--
26−-------------------------------------------------------------------------------
27−
28−{-# INLINE benchIO #-}
29−benchIO :: NFData b => String -> (Int -> IO a) -> (a -> b) -> Benchmark
30−benchIO name src f = bench name $ nfIO $
31− randomRIO (1,1) >>= src >>= return . f
32−
33−-- Drain a source that generates an array in the IO monad
34−{-# INLINE benchIOSrc #-}
35−benchIOSrc :: (NFData a)
36− => String -> (Int -> IO (Ops.Stream a)) -> Benchmark
37−benchIOSrc name src = benchIO name src id
38−
39−{-# INLINE benchPureSink #-}
40−benchPureSink :: NFData b => String -> (Ops.Stream Int -> b) -> Benchmark
41−benchPureSink name f = benchIO name Ops.sourceIntFromTo f
42−
43−{-# INLINE benchIO' #-}
44−benchIO' :: NFData b => String -> (Int -> IO a) -> (a -> IO b) -> Benchmark
45−benchIO' name src f = bench name $ nfIO $
46− randomRIO (1,1) >>= src >>= f
47−
48−{-# INLINE benchIOSink #-}
49−benchIOSink :: NFData b => String -> (Ops.Stream Int -> IO b) -> Benchmark
50−benchIOSink name f = benchIO' name Ops.sourceIntFromTo f
51−
52−mkString :: String
53−mkString =
54− "fromListN " ++
55− show (Ops.value + 1) ++ " [1" ++ concat (replicate Ops.value ",1") ++ "]"
56−
57−moduleName :: String
58−moduleName = "Data.SmallArray"
59−
60−o_1_space :: [Benchmark]
61−o_1_space =
62− [ bgroup (o_1_space_prefix moduleName)
63− [ bgroup "generation"
64− [ benchIOSrc "writeN . intFromTo" Ops.sourceIntFromTo
65− , benchIOSrc "fromList . intFromTo" Ops.sourceIntFromToFromList
66− , benchIOSrc "writeN . unfoldr" Ops.sourceUnfoldr
67− , benchIOSrc "writeN . fromList" Ops.sourceFromList
68− , mkString `deepseq` (bench "read" $ nf Ops.readInstance mkString)
69− , benchPureSink "show" Ops.showInstance
70− ]
71− , bgroup "elimination"
72− [ benchPureSink "id" id
73− , benchPureSink "==" Ops.eqInstance
74− , benchPureSink "/=" Ops.eqInstanceNotEq
75− , benchPureSink "<" Ops.ordInstance
76− , benchPureSink "min" Ops.ordInstanceMin
77− -- length is used to check for foldr/build fusion
78− -- , benchPureSink "length . IsList.toList" (length . GHC.toList)
79− , benchIOSink "foldl'" Ops.pureFoldl'
80− , benchIOSink "read" (S.drain . S.unfold A.read)
81− , benchIOSink "toStreamRev" (S.drain . A.toStreamRev)
82−#ifdef DEVBUILD
83− , benchPureSink "foldable/foldl'" Ops.foldableFoldl'
84− , benchPureSink "foldable/sum" Ops.foldableSum
85−#endif
86− ]
87− , bgroup "transformation"
88− [ benchIOSink "scanl'" (Ops.scanl' 1)
89− , benchIOSink "scanl1'" (Ops.scanl1' 1)
90− , benchIOSink "map" (Ops.map 1)
91− ]
92− , bgroup "transformationX4"
93− [ benchIOSink "scanl'" (Ops.scanl' 4)
94− , benchIOSink "scanl1'" (Ops.scanl1' 4)
95− , benchIOSink "map" (Ops.map 4)
96− ]
97− ]
98− ]
99−
100−main :: IO ()
101−main = defaultMain $ concat [o_1_space]
benchmark/Streamly/Benchmark/Data/SmallArrayOps.hsdeleted−136
@@ -1,136 +0,0 @@
1−-- |
2−-- Module : Streamly.Benchmark.Data.SmallArrayOps
3−-- Copyright : (c) 2019 Composewell Technologies
4−--
5−-- License : BSD-3-Clause
6−-- Maintainer : streamly@composewell.com
7−-- Stability : experimental
8−-- Portability : GHC
9−
10−{-# LANGUAGE CPP #-}
11−{-# LANGUAGE DeriveAnyClass #-}
12−{-# LANGUAGE DeriveGeneric #-}
13−{-# LANGUAGE FlexibleContexts #-}
14−{-# LANGUAGE ScopedTypeVariables #-}
15−
16−module Streamly.Benchmark.Data.SmallArrayOps where
17−
18−import Control.Monad.IO.Class (MonadIO)
19−import Prelude (Int, Bool, (+), ($), (==), (>), (.), Maybe(..), undefined)
20−import qualified Prelude as P
21−#ifdef DEVBUILD
22−import qualified Data.Foldable as F
23−#endif
24−
25−import qualified Streamly as S hiding (foldMapWith, runStream)
26−import qualified Streamly.Internal.Data.SmallArray as A
27−import qualified Streamly.Prelude as S
28−
29−value :: Int
30−value = 128
31−
32−-------------------------------------------------------------------------------
33−-- Benchmark ops
34−-------------------------------------------------------------------------------
35−
36−-------------------------------------------------------------------------------
37−-- Stream generation and elimination
38−-------------------------------------------------------------------------------
39−
40−type Stream = A.SmallArray
41−
42−{-# INLINE sourceUnfoldr #-}
43−sourceUnfoldr :: MonadIO m => Int -> m (Stream Int)
44−sourceUnfoldr n = S.fold (A.writeN value) $ S.unfoldr step n
45− where
46− step cnt =
47− if cnt > n + value
48− then Nothing
49− else (Just (cnt, cnt + 1))
50−
51−{-# INLINE sourceIntFromTo #-}
52−sourceIntFromTo :: MonadIO m => Int -> m (Stream Int)
53−sourceIntFromTo n = S.fold (A.writeN value) $ S.enumerateFromTo n (n + value)
54−
55−{-# INLINE sourceIntFromToFromList #-}
56−sourceIntFromToFromList :: MonadIO m => Int -> m (Stream Int)
57−sourceIntFromToFromList n = P.return $ (A.fromListN value) $ [n..n + value]
58−
59−{-# INLINE sourceFromList #-}
60−sourceFromList :: MonadIO m => Int -> m (Stream Int)
61−sourceFromList n = S.fold (A.writeN value) $ S.fromList [n..n+value]
62−
63−-------------------------------------------------------------------------------
64−-- Transformation
65−-------------------------------------------------------------------------------
66−
67−{-# INLINE composeN #-}
68−composeN :: P.Monad m
69− => Int -> (Stream Int -> m (Stream Int)) -> Stream Int -> m (Stream Int)
70−composeN n f x =
71− case n of
72− 1 -> f x
73− 2 -> f x P.>>= f
74− 3 -> f x P.>>= f P.>>= f
75− 4 -> f x P.>>= f P.>>= f P.>>= f
76− _ -> undefined
77−
78−{-# INLINE scanl' #-}
79−{-# INLINE scanl1' #-}
80−{-# INLINE map #-}
81−
82−scanl', scanl1', map
83− :: MonadIO m => Int -> Stream Int -> m (Stream Int)
84−
85−{-# INLINE onArray #-}
86−onArray
87− :: MonadIO m => (S.SerialT m Int -> S.SerialT m Int)
88− -> Stream Int
89− -> m (Stream Int)
90−onArray f arr = S.fold (A.writeN value) $ f $ (S.unfold A.read arr)
91−
92−scanl' n = composeN n $ onArray $ S.scanl' (+) 0
93−scanl1' n = composeN n $ onArray $ S.scanl1' (+)
94−map n = composeN n $ onArray $ S.map (+1)
95−
96−{-# INLINE eqInstance #-}
97−eqInstance :: Stream Int -> Bool
98−eqInstance src = src == src
99−
100−{-# INLINE eqInstanceNotEq #-}
101−eqInstanceNotEq :: Stream Int -> Bool
102−eqInstanceNotEq src = src P./= src
103−
104−{-# INLINE ordInstance #-}
105−ordInstance :: Stream Int -> Bool
106−ordInstance src = src P.< src
107−
108−{-# INLINE ordInstanceMin #-}
109−ordInstanceMin :: Stream Int -> Stream Int
110−ordInstanceMin src = P.min src src
111−
112−{-# INLINE showInstance #-}
113−showInstance :: Stream Int -> P.String
114−showInstance src = P.show src
115−
116−{-# INLINE readInstance #-}
117−readInstance :: P.String -> Stream Int
118−readInstance str =
119− let r = P.reads str
120− in case r of
121− [(x,"")] -> x
122− _ -> P.error "readInstance: no parse"
123−
124−{-# INLINE pureFoldl' #-}
125−pureFoldl' :: MonadIO m => Stream Int -> m Int
126−pureFoldl' = S.foldl' (+) 0 . S.unfold A.read
127−
128−#ifdef DEVBUILD
129−{-# INLINE foldableFoldl' #-}
130−foldableFoldl' :: Stream Int -> Int
131−foldableFoldl' = F.foldl' (+) 0
132−
133−{-# INLINE foldableSum #-}
134−foldableSum :: Stream Int -> Int
135−foldableSum = P.sum
136−#endif
benchmark/Streamly/Benchmark/Memory/Array.hsdeleted−252
@@ -1,252 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−-- |
3−-- Module : Main
4−-- Copyright : (c) 2018 Harendra Kumar
5−--
6−-- License : BSD3
7−-- Maintainer : streamly@composewell.com
8−
9−import Control.DeepSeq (NFData(..), deepseq)
10−import Foreign.Storable (Storable(..))
11−import System.Random (randomRIO)
12−
13−import qualified GHC.Exts as GHC
14−
15−import qualified Streamly.Benchmark.Memory.ArrayOps as Ops
16−import qualified Streamly.Internal.Memory.Array as IA
17−import qualified Streamly.Memory.Array as A
18−import qualified Streamly.Prelude as S
19−
20−import Streamly.Benchmark.Common hiding (benchPureSrc)
21−import Gauge
22−
23−-------------------------------------------------------------------------------
24−--
25−-------------------------------------------------------------------------------
26−
27−-- Drain a source that generates a pure array
28−{-# INLINE benchPureSrc #-}
29−benchPureSrc :: (NFData a, Storable a)
30− => String -> (Int -> Ops.Stream a) -> Benchmark
31−benchPureSrc name src = benchPure name src id
32−
33−{-# INLINE benchIO #-}
34−benchIO :: NFData b => String -> (Int -> IO a) -> (a -> b) -> Benchmark
35−benchIO name src f = bench name $ nfIO $
36− randomRIO (1,1) >>= src >>= return . f
37−
38−-- Drain a source that generates an array in the IO monad
39−{-# INLINE benchIOSrc #-}
40−benchIOSrc :: (NFData a, Storable a)
41− => String -> (Int -> IO (Ops.Stream a)) -> Benchmark
42−benchIOSrc name src = benchIO name src id
43−
44−{-# INLINE benchPureSink #-}
45−benchPureSink :: NFData b => String -> (Ops.Stream Int -> b) -> Benchmark
46−benchPureSink name f = benchIO name Ops.sourceIntFromTo f
47−
48−{-# INLINE benchIO' #-}
49−benchIO' :: NFData b => String -> (Int -> IO a) -> (a -> IO b) -> Benchmark
50−benchIO' name src f = bench name $ nfIO $
51− randomRIO (1,1) >>= src >>= f
52−
53−{-# INLINE benchIOSink #-}
54−benchIOSink :: NFData b => String -> (Ops.Stream Int -> IO b) -> Benchmark
55−benchIOSink name f = benchIO' name Ops.sourceIntFromTo f
56−
57−testStr :: String
58−testStr = mkListString Ops.value
59−
60−moduleName :: String
61−moduleName = "Memory.Array"
62−
63−o_1_space :: [Benchmark]
64−o_1_space =
65− [ bgroup (o_1_space_prefix moduleName)
66− [ bgroup "generation"
67− [ benchIOSrc "writeN . intFromTo" Ops.sourceIntFromTo
68− , benchIOSrc "write . intFromTo" Ops.sourceIntFromToFromStream
69− , benchIOSrc "fromList . intFromTo" Ops.sourceIntFromToFromList
70− , benchIOSrc "writeN . unfoldr" Ops.sourceUnfoldr
71− , benchIOSrc "writeN . fromList" Ops.sourceFromList
72− , benchPureSrc "writeN . IsList.fromList" Ops.sourceIsList
73− , benchPureSrc "writeN . IsString.fromString" Ops.sourceIsString
74− , testStr `deepseq` (bench "read" $ nf Ops.readInstance testStr)
75− , benchPureSink "show" Ops.showInstance
76− ]
77− , bgroup "elimination"
78− [ benchPureSink "id" id
79− -- , benchPureSink "eqBy" Ops.eqBy
80− , benchPureSink "==" Ops.eqInstance
81− , benchPureSink "/=" Ops.eqInstanceNotEq
82− {-
83− , benchPureSink "cmpBy" Ops.cmpBy
84− -}
85− , benchPureSink "<" Ops.ordInstance
86− , benchPureSink "min" Ops.ordInstanceMin
87− -- length is used to check for foldr/build fusion
88− , benchPureSink "length . IsList.toList" (length . GHC.toList)
89− , benchIOSink "foldl'" Ops.pureFoldl'
90− , benchIOSink "read" (S.drain . S.unfold A.read)
91− , benchIOSink "toStreamRev" (S.drain . IA.toStreamRev)
92−#ifdef DEVBUILD
93− , benchPureSink "foldable/foldl'" Ops.foldableFoldl'
94− , benchPureSink "foldable/sum" Ops.foldableSum
95− -- , benchPureSinkIO "traversable/mapM" Ops.traversableMapM
96−#endif
97− ]
98−
99− {-
100− [ benchPureSink "uncons" Ops.uncons
101− , benchPureSink "toNull" $ Ops.toNull serially
102− , benchPureSink "mapM_" Ops.mapM_
103−
104− , benchPureSink "init" Ops.init
105− , benchPureSink "tail" Ops.tail
106− , benchPureSink "nullHeadTail" Ops.nullHeadTail
107−
108− -- this is too low and causes all benchmarks reported in ns
109− -- , benchPureSink "head" Ops.head
110− , benchPureSink "last" Ops.last
111− -- , benchPureSink "lookup" Ops.lookup
112− , benchPureSink "find" Ops.find
113− , benchPureSink "findIndex" Ops.findIndex
114− , benchPureSink "elemIndex" Ops.elemIndex
115−
116− -- this is too low and causes all benchmarks reported in ns
117− -- , benchPureSink "null" Ops.null
118− , benchPureSink "elem" Ops.elem
119− , benchPureSink "notElem" Ops.notElem
120− , benchPureSink "all" Ops.all
121− , benchPureSink "any" Ops.any
122− , benchPureSink "and" Ops.and
123− , benchPureSink "or" Ops.or
124−
125− , benchPureSink "length" Ops.length
126− , benchPureSink "sum" Ops.sum
127− , benchPureSink "product" Ops.product
128−
129− , benchPureSink "maximumBy" Ops.maximumBy
130− , benchPureSink "maximum" Ops.maximum
131− , benchPureSink "minimumBy" Ops.minimumBy
132− , benchPureSink "minimum" Ops.minimum
133−
134− , benchPureSink "toList" Ops.toList
135− , benchPureSink "toRevList" Ops.toRevList
136− ]
137− -}
138− , bgroup "transformation"
139− [ benchIOSink "scanl'" (Ops.scanl' 1)
140− , benchIOSink "scanl1'" (Ops.scanl1' 1)
141− , benchIOSink "map" (Ops.map 1)
142− {-
143− , benchPureSink "fmap" (Ops.fmap 1)
144− , benchPureSink "mapM" (Ops.mapM serially 1)
145− , benchPureSink "mapMaybe" (Ops.mapMaybe 1)
146− , benchPureSink "mapMaybeM" (Ops.mapMaybeM 1)
147− , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
148− Ops.sequence serially (Ops.sourceUnfoldrMAction n)
149− , benchPureSink "findIndices" (Ops.findIndices 1)
150− , benchPureSink "elemIndices" (Ops.elemIndices 1)
151− , benchPureSink "reverse" (Ops.reverse 1)
152− , benchPureSink "foldrS" (Ops.foldrS 1)
153− , benchPureSink "foldrSMap" (Ops.foldrSMap 1)
154− , benchPureSink "foldrT" (Ops.foldrT 1)
155− , benchPureSink "foldrTMap" (Ops.foldrTMap 1)
156− -}
157− ]
158− , bgroup "transformationX4"
159− [ benchIOSink "scanl'" (Ops.scanl' 4)
160− , benchIOSink "scanl1'" (Ops.scanl1' 4)
161− , benchIOSink "map" (Ops.map 4)
162− {-
163− , benchPureSink "fmap" (Ops.fmap 4)
164− , benchPureSink "mapM" (Ops.mapM serially 4)
165− , benchPureSink "mapMaybe" (Ops.mapMaybe 4)
166− , benchPureSink "mapMaybeM" (Ops.mapMaybeM 4)
167− -- , bench "sequence" $ nfIO $ randomRIO (1,1000) >>= \n ->
168− -- Ops.sequence serially (Ops.sourceUnfoldrMAction n)
169− , benchPureSink "findIndices" (Ops.findIndices 4)
170− , benchPureSink "elemIndices" (Ops.elemIndices 4)
171− -}
172− ]
173− {-
174− , bgroup "filtering"
175− [ benchPureSink "filter-even" (Ops.filterEven 1)
176− , benchPureSink "filter-all-out" (Ops.filterAllOut 1)
177− , benchPureSink "filter-all-in" (Ops.filterAllIn 1)
178− , benchPureSink "take-all" (Ops.takeAll 1)
179− , benchPureSink "takeWhile-true" (Ops.takeWhileTrue 1)
180− --, benchPureSink "takeWhileM-true" (Ops.takeWhileMTrue 1)
181− , benchPureSink "drop-one" (Ops.dropOne 1)
182− , benchPureSink "drop-all" (Ops.dropAll 1)
183− , benchPureSink "dropWhile-true" (Ops.dropWhileTrue 1)
184− --, benchPureSink "dropWhileM-true" (Ops.dropWhileMTrue 1)
185− , benchPureSink "dropWhile-false" (Ops.dropWhileFalse 1)
186− , benchPureSink "deleteBy" (Ops.deleteBy 1)
187− , benchPureSink "insertBy" (Ops.insertBy 1)
188− ]
189− , bgroup "filteringX4"
190− [ benchPureSink "filter-even" (Ops.filterEven 4)
191− , benchPureSink "filter-all-out" (Ops.filterAllOut 4)
192− , benchPureSink "filter-all-in" (Ops.filterAllIn 4)
193− , benchPureSink "take-all" (Ops.takeAll 4)
194− , benchPureSink "takeWhile-true" (Ops.takeWhileTrue 4)
195− --, benchPureSink "takeWhileM-true" (Ops.takeWhileMTrue 4)
196− , benchPureSink "drop-one" (Ops.dropOne 4)
197− , benchPureSink "drop-all" (Ops.dropAll 4)
198− , benchPureSink "dropWhile-true" (Ops.dropWhileTrue 4)
199− --, benchPureSink "dropWhileM-true" (Ops.dropWhileMTrue 4)
200− , benchPureSink "dropWhile-false" (Ops.dropWhileFalse 4)
201− , benchPureSink "deleteBy" (Ops.deleteBy 4)
202− , benchPureSink "insertBy" (Ops.insertBy 4)
203− ]
204− , bgroup "multi-stream"
205− [ benchPureSink "eqBy" Ops.eqBy
206− , benchPureSink "cmpBy" Ops.cmpBy
207− , benchPureSink "zip" Ops.zip
208− , benchPureSink "zipM" Ops.zipM
209− , benchPureSink "mergeBy" Ops.mergeBy
210− , benchPureSink "isPrefixOf" Ops.isPrefixOf
211− , benchPureSink "isSubsequenceOf" Ops.isSubsequenceOf
212− , benchPureSink "stripPrefix" Ops.stripPrefix
213− , benchPureSrc serially "concatMap" Ops.concatMap
214− ]
215− -- scanl-map and foldl-map are equivalent to the scan and fold in the foldl
216− -- library. If scan/fold followed by a map is efficient enough we may not
217− -- need monolithic implementations of these.
218− , bgroup "mixed"
219− [ benchPureSink "scanl-map" (Ops.scanMap 1)
220− , benchPureSink "foldl-map" Ops.foldl'ReduceMap
221− , benchPureSink "sum-product-fold" Ops.sumProductFold
222− , benchPureSink "sum-product-scan" Ops.sumProductScan
223− ]
224− , bgroup "mixedX4"
225− [ benchPureSink "scan-map" (Ops.scanMap 4)
226− , benchPureSink "drop-map" (Ops.dropMap 4)
227− , benchPureSink "drop-scan" (Ops.dropScan 4)
228− , benchPureSink "take-drop" (Ops.takeDrop 4)
229− , benchPureSink "take-scan" (Ops.takeScan 4)
230− , benchPureSink "take-map" (Ops.takeMap 4)
231− , benchPureSink "filter-drop" (Ops.filterDrop 4)
232− , benchPureSink "filter-take" (Ops.filterTake 4)
233− , benchPureSink "filter-scan" (Ops.filterScan 4)
234− , benchPureSink "filter-scanl1" (Ops.filterScanl1 4)
235− , benchPureSink "filter-map" (Ops.filterMap 4)
236− ]
237− , bgroup "iterated"
238− [ benchPureSrc serially "mapM" Ops.iterateMapM
239− , benchPureSrc serially "scan(1/100)" Ops.iterateScan
240− , benchPureSrc serially "scanl1(1/100)" Ops.iterateScanl1
241− , benchPureSrc serially "filterEven" Ops.iterateFilterEven
242− , benchPureSrc serially "takeAll" Ops.iterateTakeAll
243− , benchPureSrc serially "dropOne" Ops.iterateDropOne
244− , benchPureSrc serially "dropWhileFalse" Ops.iterateDropWhileFalse
245− , benchPureSrc serially "dropWhileTrue" Ops.iterateDropWhileTrue
246− ]
247− -}
248− ]
249− ]
250−
251−main :: IO ()
252−main = defaultMain $ concat [o_1_space]
benchmark/Streamly/Benchmark/Memory/ArrayOps.hsdeleted−531
@@ -1,531 +0,0 @@
1−-- |
2−-- Module : ArrayOps
3−-- Copyright : (c) 2018 Harendra Kumar
4−--
5−-- License : MIT
6−-- Maintainer : streamly@composewell.com
7−
8−{-# LANGUAGE CPP #-}
9−{-# LANGUAGE FlexibleContexts #-}
10−{-# LANGUAGE ScopedTypeVariables #-}
11−{-# LANGUAGE DeriveAnyClass #-}
12−{-# LANGUAGE DeriveGeneric #-}
13−
14−module Streamly.Benchmark.Memory.ArrayOps where
15−
16−-- import Control.Monad (when)
17−import Control.Monad.IO.Class (MonadIO)
18−-- import Data.Maybe (fromJust)
19−import Prelude (Int, Bool, (+), ($), (==), (>), (.), Maybe(..), undefined)
20−import qualified Prelude as P
21−#ifdef DEVBUILD
22−import qualified Data.Foldable as F
23−#endif
24−import qualified GHC.Exts as GHC
25−-- import Control.DeepSeq (NFData)
26−-- import GHC.Generics (Generic)
27−
28−import qualified Streamly as S hiding (foldMapWith, runStream)
29−import qualified Streamly.Memory.Array as A
30−import qualified Streamly.Prelude as S
31−
32−value, maxValue :: Int
33−#ifdef LINEAR_ASYNC
34−value = 10000
35−#else
36−value = 100000
37−#endif
38−maxValue = value + 1
39−
40−-------------------------------------------------------------------------------
41−-- Benchmark ops
42−-------------------------------------------------------------------------------
43−
44−-------------------------------------------------------------------------------
45−-- Stream generation and elimination
46−-------------------------------------------------------------------------------
47−
48−type Stream = A.Array
49−
50−{-# INLINE sourceUnfoldr #-}
51−sourceUnfoldr :: MonadIO m => Int -> m (Stream Int)
52−sourceUnfoldr n = S.fold (A.writeN value) $ S.unfoldr step n
53− where
54− step cnt =
55− if cnt > n + value
56− then Nothing
57− else (Just (cnt, cnt + 1))
58−
59−{-# INLINE sourceIntFromTo #-}
60−sourceIntFromTo :: MonadIO m => Int -> m (Stream Int)
61−sourceIntFromTo n = S.fold (A.writeN value) $ S.enumerateFromTo n (n + value)
62−
63−{-# INLINE sourceIntFromToFromStream #-}
64−sourceIntFromToFromStream :: MonadIO m => Int -> m (Stream Int)
65−sourceIntFromToFromStream n = S.fold A.write $ S.enumerateFromTo n (n + value)
66−
67−sourceIntFromToFromList :: MonadIO m => Int -> m (Stream Int)
68−sourceIntFromToFromList n = P.return $ A.fromList $ [n..n + value]
69−
70−{-# INLINE sourceFromList #-}
71−sourceFromList :: MonadIO m => Int -> m (Stream Int)
72−sourceFromList n = S.fold (A.writeN value) $ S.fromList [n..n+value]
73−
74−{-# INLINE sourceIsList #-}
75−sourceIsList :: Int -> Stream Int
76−sourceIsList n = GHC.fromList [n..n+value]
77−
78−{-# INLINE sourceIsString #-}
79−sourceIsString :: Int -> Stream P.Char
80−sourceIsString n = GHC.fromString (P.replicate (n + value) 'a')
81−
82−{-
83−-------------------------------------------------------------------------------
84−-- Elimination
85−-------------------------------------------------------------------------------
86−
87−{-# INLINE runStream #-}
88−runStream :: Monad m => Stream m a -> m ()
89−runStream = S.runStream
90−
91−{-# INLINE toList #-}
92−toList :: Monad m => Stream m Int -> m [Int]
93−
94−{-# INLINE head #-}
95−{-# INLINE last #-}
96−{-# INLINE maximum #-}
97−{-# INLINE minimum #-}
98−{-# INLINE find #-}
99−{-# INLINE findIndex #-}
100−{-# INLINE elemIndex #-}
101−{-# INLINE foldl1'Reduce #-}
102−head, last, minimum, maximum, find, findIndex, elemIndex, foldl1'Reduce
103− :: Monad m => Stream m Int -> m (Maybe Int)
104−
105−{-# INLINE minimumBy #-}
106−{-# INLINE maximumBy #-}
107−minimumBy, maximumBy :: Monad m => Stream m Int -> m (Maybe Int)
108−
109−{-# INLINE foldl'Reduce #-}
110−{-# INLINE foldl'ReduceMap #-}
111−{-# INLINE foldlM'Reduce #-}
112−{-# INLINE foldrMReduce #-}
113−{-# INLINE length #-}
114−{-# INLINE sum #-}
115−{-# INLINE product #-}
116−foldl'Reduce, foldl'ReduceMap, foldlM'Reduce, foldrMReduce, length, sum, product
117− :: Monad m
118− => Stream m Int -> m Int
119−
120−{-# INLINE foldl'Build #-}
121−{-# INLINE foldlM'Build #-}
122−{-# INLINE foldrMBuild #-}
123−foldrMBuild, foldl'Build, foldlM'Build
124− :: Monad m
125− => Stream m Int -> m [Int]
126−
127−{-# INLINE all #-}
128−{-# INLINE any #-}
129−{-# INLINE and #-}
130−{-# INLINE or #-}
131−{-# INLINE null #-}
132−{-# INLINE elem #-}
133−{-# INLINE notElem #-}
134−null, elem, notElem, all, any, and, or :: Monad m => Stream m Int -> m Bool
135−
136−{-# INLINE toNull #-}
137−toNull :: Monad m => (t m a -> S.SerialT m a) -> t m a -> m ()
138−toNull t = runStream . t
139−
140−{-# INLINE uncons #-}
141−uncons :: Monad m => Stream m Int -> m ()
142−uncons s = do
143− r <- S.uncons s
144− case r of
145− Nothing -> return ()
146− Just (_, t) -> uncons t
147−
148−{-# INLINE init #-}
149−init :: Monad m => Stream m a -> m ()
150−init s = S.init s >>= Prelude.mapM_ S.runStream
151−
152−{-# INLINE tail #-}
153−tail :: Monad m => Stream m a -> m ()
154−tail s = S.tail s >>= Prelude.mapM_ tail
155−
156−{-# INLINE nullHeadTail #-}
157−nullHeadTail :: Monad m => Stream m Int -> m ()
158−nullHeadTail s = do
159− r <- S.null s
160− when (not r) $ do
161− _ <- S.head s
162− S.tail s >>= Prelude.mapM_ nullHeadTail
163−
164−{-# INLINE mapM_ #-}
165−mapM_ :: Monad m => Stream m Int -> m ()
166−mapM_ = S.mapM_ (\_ -> return ())
167−
168−toList = S.toList
169−
170−{-# INLINE toRevList #-}
171−toRevList :: Monad m => Stream m Int -> m [Int]
172−toRevList = S.toRevList
173−
174−foldrMBuild = S.foldrM (\x xs -> xs >>= return . (x :)) (return [])
175−foldl'Build = S.foldl' (flip (:)) []
176−foldlM'Build = S.foldlM' (\xs x -> return $ x : xs) (return [])
177−
178−foldrMReduce = S.foldrM (\x xs -> xs >>= return . (x +)) (return 0)
179−foldl'Reduce = S.foldl' (+) 0
180−foldl'ReduceMap = P.fmap (+1) . S.foldl' (+) 0
181−foldl1'Reduce = S.foldl1' (+)
182−foldlM'Reduce = S.foldlM' (\xs a -> return $ a + xs) (return 0)
183−
184−last = S.last
185−null = S.null
186−head = S.head
187−elem = S.elem maxValue
188−notElem = S.notElem maxValue
189−length = S.length
190−all = S.all (<= maxValue)
191−any = S.any (> maxValue)
192−and = S.and . S.map (<= maxValue)
193−or = S.or . S.map (> maxValue)
194−find = S.find (== maxValue)
195−findIndex = S.findIndex (== maxValue)
196−elemIndex = S.elemIndex maxValue
197−maximum = S.maximum
198−minimum = S.minimum
199−sum = S.sum
200−product = S.product
201−minimumBy = S.minimumBy compare
202−maximumBy = S.maximumBy compare
203−-}
204−
205−-------------------------------------------------------------------------------
206−-- Transformation
207−-------------------------------------------------------------------------------
208−
209−{-
210−{-# INLINE transform #-}
211−transform :: Stream a -> Stream a
212−transform = P.id
213−-}
214−
215−{-# INLINE composeN #-}
216−composeN :: P.Monad m
217− => Int -> (Stream Int -> m (Stream Int)) -> Stream Int -> m (Stream Int)
218−composeN n f x =
219− case n of
220− 1 -> f x
221− 2 -> f x P.>>= f
222− 3 -> f x P.>>= f P.>>= f
223− 4 -> f x P.>>= f P.>>= f P.>>= f
224− _ -> undefined
225−
226−{-# INLINE scanl' #-}
227−{-# INLINE scanl1' #-}
228−{-# INLINE map #-}
229−{-
230−{-# INLINE fmap #-}
231−{-# INLINE mapMaybe #-}
232−{-# INLINE filterEven #-}
233−{-# INLINE filterAllOut #-}
234−{-# INLINE filterAllIn #-}
235−{-# INLINE takeOne #-}
236−{-# INLINE takeAll #-}
237−{-# INLINE takeWhileTrue #-}
238−{-# INLINE takeWhileMTrue #-}
239−{-# INLINE dropOne #-}
240−{-# INLINE dropAll #-}
241−{-# INLINE dropWhileTrue #-}
242−{-# INLINE dropWhileMTrue #-}
243−{-# INLINE dropWhileFalse #-}
244−{-# INLINE findIndices #-}
245−{-# INLINE elemIndices #-}
246−{-# INLINE insertBy #-}
247−{-# INLINE deleteBy #-}
248−{-# INLINE reverse #-}
249−{-# INLINE foldrS #-}
250−{-# INLINE foldrSMap #-}
251−{-# INLINE foldrT #-}
252−{-# INLINE foldrTMap #-}
253− -}
254−scanl' , scanl1', map{-, fmap, mapMaybe, filterEven, filterAllOut,
255− filterAllIn, takeOne, takeAll, takeWhileTrue, takeWhileMTrue, dropOne,
256− dropAll, dropWhileTrue, dropWhileMTrue, dropWhileFalse,
257− findIndices, elemIndices, insertBy, deleteBy, reverse,
258− foldrS, foldrSMap, foldrT, foldrTMap -}
259− :: MonadIO m => Int -> Stream Int -> m (Stream Int)
260−
261−{-
262−{-# INLINE mapMaybeM #-}
263−mapMaybeM :: S.MonadAsync m => Int -> Stream m Int -> m ()
264−
265−{-# INLINE mapM #-}
266−{-# INLINE map' #-}
267−{-# INLINE fmap' #-}
268−mapM, map' :: (S.IsStream t, S.MonadAsync m)
269− => (t m Int -> S.SerialT m Int) -> Int -> t m Int -> m ()
270−
271−fmap' :: (S.IsStream t, S.MonadAsync m, P.Functor (t m))
272− => (t m Int -> S.SerialT m Int) -> Int -> t m Int -> m ()
273−
274−{-# INLINE sequence #-}
275−sequence :: (S.IsStream t, S.MonadAsync m)
276− => (t m Int -> S.SerialT m Int) -> t m (m Int) -> m ()
277− -}
278−
279−{-# INLINE onArray #-}
280−onArray
281− :: MonadIO m => (S.SerialT m Int -> S.SerialT m Int)
282− -> Stream Int
283− -> m (Stream Int)
284−onArray f arr = S.fold (A.writeN value) $ f $ (S.unfold A.read arr)
285−
286−scanl' n = composeN n $ onArray $ S.scanl' (+) 0
287−scanl1' n = composeN n $ onArray $ S.scanl1' (+)
288−map n = composeN n $ onArray $ S.map (+1)
289−-- map n = composeN n $ A.map (+1)
290−{-
291−fmap n = composeN n $ Prelude.fmap (+1)
292−fmap' t n = composeN' n $ t . Prelude.fmap (+1)
293−map' t n = composeN' n $ t . S.map (+1)
294−mapM t n = composeN' n $ t . S.mapM return
295−mapMaybe n = composeN n $ S.mapMaybe
296− (\x -> if Prelude.odd x then Nothing else Just x)
297−mapMaybeM n = composeN n $ S.mapMaybeM
298− (\x -> if Prelude.odd x then return Nothing else return $ Just x)
299−sequence t = transform . t . S.sequence
300−filterEven n = composeN n $ S.filter even
301−filterAllOut n = composeN n $ S.filter (> maxValue)
302−filterAllIn n = composeN n $ S.filter (<= maxValue)
303−takeOne n = composeN n $ S.take 1
304−takeAll n = composeN n $ S.take maxValue
305−takeWhileTrue n = composeN n $ S.takeWhile (<= maxValue)
306−takeWhileMTrue n = composeN n $ S.takeWhileM (return . (<= maxValue))
307−dropOne n = composeN n $ S.drop 1
308−dropAll n = composeN n $ S.drop maxValue
309−dropWhileTrue n = composeN n $ S.dropWhile (<= maxValue)
310−dropWhileMTrue n = composeN n $ S.dropWhileM (return . (<= maxValue))
311−dropWhileFalse n = composeN n $ S.dropWhile (> maxValue)
312−findIndices n = composeN n $ S.findIndices (== maxValue)
313−elemIndices n = composeN n $ S.elemIndices maxValue
314−insertBy n = composeN n $ S.insertBy compare maxValue
315−deleteBy n = composeN n $ S.deleteBy (>=) maxValue
316−reverse n = composeN n $ S.reverse
317−foldrS n = composeN n $ S.foldrS S.cons S.nil
318−foldrSMap n = composeN n $ S.foldrS (\x xs -> x + 1 `S.cons` xs) S.nil
319−foldrT n = composeN n $ S.foldrT S.cons S.nil
320−foldrTMap n = composeN n $ S.foldrT (\x xs -> x + 1 `S.cons` xs) S.nil
321−
322−-------------------------------------------------------------------------------
323−-- Iteration
324−-------------------------------------------------------------------------------
325−
326−iterStreamLen, maxIters :: Int
327−iterStreamLen = 10
328−maxIters = 10000
329−
330−{-# INLINE iterateSource #-}
331−iterateSource
332− :: S.MonadAsync m
333− => (Stream m Int -> Stream m Int) -> Int -> Int -> Stream m Int
334−iterateSource g i n = f i (sourceUnfoldrMN iterStreamLen n)
335− where
336− f (0 :: Int) m = g m
337− f x m = g (f (x P.- 1) m)
338−
339−{-# INLINE iterateMapM #-}
340−{-# INLINE iterateScan #-}
341−{-# INLINE iterateScanl1 #-}
342−{-# INLINE iterateFilterEven #-}
343−{-# INLINE iterateTakeAll #-}
344−{-# INLINE iterateDropOne #-}
345−{-# INLINE iterateDropWhileFalse #-}
346−{-# INLINE iterateDropWhileTrue #-}
347−iterateMapM, iterateScan, iterateScanl1, iterateFilterEven, iterateTakeAll,
348− iterateDropOne, iterateDropWhileFalse, iterateDropWhileTrue
349− :: S.MonadAsync m
350− => Int -> Stream m Int
351−
352−-- this is quadratic
353−iterateScan = iterateSource (S.scanl' (+) 0) (maxIters `div` 10)
354−-- so is this
355−iterateScanl1 = iterateSource (S.scanl1' (+)) (maxIters `div` 10)
356−
357−iterateMapM = iterateSource (S.mapM return) maxIters
358−iterateFilterEven = iterateSource (S.filter even) maxIters
359−iterateTakeAll = iterateSource (S.take maxValue) maxIters
360−iterateDropOne = iterateSource (S.drop 1) maxIters
361−iterateDropWhileFalse = iterateSource (S.dropWhile (> maxValue)) maxIters
362−iterateDropWhileTrue = iterateSource (S.dropWhile (<= maxValue)) maxIters
363−
364−-------------------------------------------------------------------------------
365−-- Zipping and concat
366−-------------------------------------------------------------------------------
367−
368−{-# INLINE zip #-}
369−{-# INLINE zipM #-}
370−{-# INLINE mergeBy #-}
371−zip, zipM, mergeBy :: Monad m => Stream m Int -> m ()
372−
373−zip src = do
374− r <- S.tail src
375− let src1 = fromJust r
376− transform (S.zipWith (,) src src1)
377−zipM src = do
378− r <- S.tail src
379− let src1 = fromJust r
380− transform (S.zipWithM (curry return) src src1)
381−
382−mergeBy src = do
383− r <- S.tail src
384− let src1 = fromJust r
385− transform (S.mergeBy P.compare src src1)
386−
387−{-# INLINE isPrefixOf #-}
388−{-# INLINE isSubsequenceOf #-}
389−isPrefixOf, isSubsequenceOf :: Monad m => Stream m Int -> m Bool
390−
391−isPrefixOf src = S.isPrefixOf src src
392−isSubsequenceOf src = S.isSubsequenceOf src src
393−
394−{-# INLINE stripPrefix #-}
395−stripPrefix :: Monad m => Stream m Int -> m ()
396−stripPrefix src = do
397− _ <- S.stripPrefix src src
398− return ()
399−
400−{-# INLINE zipAsync #-}
401−{-# INLINE zipAsyncM #-}
402−{-# INLINE zipAsyncAp #-}
403−zipAsync, zipAsyncAp, zipAsyncM :: S.MonadAsync m => Stream m Int -> m ()
404−
405−zipAsync src = do
406− r <- S.tail src
407− let src1 = fromJust r
408− transform (S.zipAsyncWith (,) src src1)
409−
410−zipAsyncM src = do
411− r <- S.tail src
412− let src1 = fromJust r
413− transform (S.zipAsyncWithM (curry return) src src1)
414−
415−zipAsyncAp src = do
416− r <- S.tail src
417− let src1 = fromJust r
418− transform (S.zipAsyncly $ (,) <$> S.serially src
419− <*> S.serially src1)
420−
421−{-# INLINE eqBy #-}
422−eqBy :: (Monad m, P.Eq a) => Stream m a -> m P.Bool
423−eqBy src = S.eqBy (==) src src
424−
425−{-# INLINE cmpBy #-}
426−cmpBy :: (Monad m, P.Ord a) => Stream m a -> m P.Ordering
427−cmpBy src = S.cmpBy P.compare src src
428−
429−concatStreamLen, maxNested :: Int
430−concatStreamLen = 1
431−maxNested = 100000
432−
433−{-# INLINE concatMap #-}
434−concatMap :: S.MonadAsync m => Int -> Stream m Int
435−concatMap n = S.concatMap (\_ -> sourceUnfoldrMN maxNested n)
436− (sourceUnfoldrMN concatStreamLen n)
437−
438−-------------------------------------------------------------------------------
439−-- Mixed Composition
440−-------------------------------------------------------------------------------
441−
442−{-# INLINE scanMap #-}
443−{-# INLINE dropMap #-}
444−{-# INLINE dropScan #-}
445−{-# INLINE takeDrop #-}
446−{-# INLINE takeScan #-}
447−{-# INLINE takeMap #-}
448−{-# INLINE filterDrop #-}
449−{-# INLINE filterTake #-}
450−{-# INLINE filterScan #-}
451−{-# INLINE filterScanl1 #-}
452−{-# INLINE filterMap #-}
453−scanMap, dropMap, dropScan, takeDrop, takeScan, takeMap, filterDrop,
454− filterTake, filterScan, filterScanl1, filterMap
455− :: Monad m => Int -> Stream m Int -> m ()
456−
457−scanMap n = composeN n $ S.map (subtract 1) . S.scanl' (+) 0
458−dropMap n = composeN n $ S.map (subtract 1) . S.drop 1
459−dropScan n = composeN n $ S.scanl' (+) 0 . S.drop 1
460−takeDrop n = composeN n $ S.drop 1 . S.take maxValue
461−takeScan n = composeN n $ S.scanl' (+) 0 . S.take maxValue
462−takeMap n = composeN n $ S.map (subtract 1) . S.take maxValue
463−filterDrop n = composeN n $ S.drop 1 . S.filter (<= maxValue)
464−filterTake n = composeN n $ S.take maxValue . S.filter (<= maxValue)
465−filterScan n = composeN n $ S.scanl' (+) 0 . S.filter (<= maxBound)
466−filterScanl1 n = composeN n $ S.scanl1' (+) . S.filter (<= maxBound)
467−filterMap n = composeN n $ S.map (subtract 1) . S.filter (<= maxValue)
468−
469−data Pair a b = Pair !a !b deriving (Generic, NFData)
470−
471−{-# INLINE sumProductFold #-}
472−sumProductFold :: Monad m => Stream m Int -> m (Int, Int)
473−sumProductFold = S.foldl' (\(s,p) x -> (s + x, p P.* x)) (0,1)
474−
475−{-# INLINE sumProductScan #-}
476−sumProductScan :: Monad m => Stream m Int -> m (Pair Int Int)
477−sumProductScan = S.foldl' (\(Pair _ p) (s0,x) -> Pair s0 (p P.* x)) (Pair 0 1)
478− . S.scanl' (\(s,_) x -> (s + x,x)) (0,0)
479−
480−-------------------------------------------------------------------------------
481−-- Pure stream operations
482−-------------------------------------------------------------------------------
483−
484−-}
485−{-# INLINE eqInstance #-}
486−eqInstance :: Stream Int -> Bool
487−eqInstance src = src == src
488−
489−{-# INLINE eqInstanceNotEq #-}
490−eqInstanceNotEq :: Stream Int -> Bool
491−eqInstanceNotEq src = src P./= src
492−
493−{-# INLINE ordInstance #-}
494−ordInstance :: Stream Int -> Bool
495−ordInstance src = src P.< src
496−
497−{-# INLINE ordInstanceMin #-}
498−ordInstanceMin :: Stream Int -> Stream Int
499−ordInstanceMin src = P.min src src
500−
501−{-# INLINE showInstance #-}
502−showInstance :: Stream Int -> P.String
503−showInstance src = P.show src
504−
505−{-# INLINE readInstance #-}
506−readInstance :: P.String -> Stream Int
507−readInstance str =
508− let r = P.reads str
509− in case r of
510− [(x,"")] -> x
511− _ -> P.error "readInstance: no parse"
512−
513−{-# INLINE pureFoldl' #-}
514−pureFoldl' :: MonadIO m => Stream Int -> m Int
515−pureFoldl' = S.foldl' (+) 0 . S.unfold A.read
516−
517−#ifdef DEVBUILD
518−{-# INLINE foldableFoldl' #-}
519−foldableFoldl' :: Stream Int -> Int
520−foldableFoldl' = F.foldl' (+) 0
521−
522−{-# INLINE foldableSum #-}
523−foldableSum :: Stream Int -> Int
524−foldableSum = P.sum
525−#endif
526−
527−{-
528−{-# INLINE traversableMapM #-}
529−traversableMapM :: Stream Identity Int -> IO (Stream Identity Int)
530−traversableMapM = P.mapM return
531−-}
benchmark/streamly-benchmarks.cabal+11−6
@@ -385,27 +385,32 @@ benchmark Data.Array
385385 hs-source-dirs: .
386386 main-is: Streamly/Benchmark/Data/Array.hs
387387 other-modules: Streamly.Benchmark.Data.ArrayOps
388+ cpp-options: -DDATA_ARRAY
388389
389390benchmark Data.Prim.Array
390391 import: bench-options
391392 type: exitcode-stdio-1.0
392393 hs-source-dirs: .
393− main-is: Streamly/Benchmark/Data/Prim/Array.hs
394− other-modules: Streamly.Benchmark.Data.Prim.ArrayOps
394+ main-is: Streamly/Benchmark/Data/Array.hs
395+ other-modules: Streamly.Benchmark.Data.ArrayOps
396+ cpp-options: -DDATA_PRIM_ARRAY
397+ build-depends: primitive
395398
396399benchmark Data.SmallArray
397400 import: bench-options
398401 type: exitcode-stdio-1.0
399402 hs-source-dirs: .
400− main-is: Streamly/Benchmark/Data/SmallArray.hs
401− other-modules: Streamly.Benchmark.Data.SmallArrayOps
403+ main-is: Streamly/Benchmark/Data/Array.hs
404+ other-modules: Streamly.Benchmark.Data.ArrayOps
405+ cpp-options: -DDATA_SMALLARRAY
402406
403407benchmark Memory.Array
404408 import: bench-options
405409 type: exitcode-stdio-1.0
406410 hs-source-dirs: .
407− main-is: Streamly/Benchmark/Memory/Array.hs
408− other-modules: Streamly.Benchmark.Memory.ArrayOps
411+ main-is: Streamly/Benchmark/Data/Array.hs
412+ other-modules: Streamly.Benchmark.Data.ArrayOps
413+ cpp-options: -DMEMORY_ARRAY
409414
410415-------------------------------------------------------------------------------
411416-- FileIO Benchmarks
streamly.cabal−2
@@ -112,11 +112,9 @@ extra-source-files:
112112 benchmark/README.md
113113 benchmark/Streamly/Benchmark/Data/*.hs
114114 benchmark/Streamly/Benchmark/Data/Parser/*.hs
115− benchmark/Streamly/Benchmark/Data/Prim/*.hs
116115 benchmark/Streamly/Benchmark/Data/Stream/*.hs
117116 benchmark/Streamly/Benchmark/FileSystem/*.hs
118117 benchmark/Streamly/Benchmark/FileSystem/Handle/*.hs
119− benchmark/Streamly/Benchmark/Memory/*.hs
120118 benchmark/Streamly/Benchmark/Prelude/*.hs
121119 benchmark/lib/Streamly/Benchmark/*.hs
122120 benchmark/streamly-benchmarks.cabal