on b339cf8 help sign in
180 lines 5.6 kB history raw
1-- |
2-- Module : Main
3-- Copyright : (c) 2020 Composewell Technologies
4--
5-- License : BSD-3-Clause
6-- Maintainer : streamly@composewell.com
8{-# LANGUAGE CPP #-}
10import Control.DeepSeq (NFData(..))
11import System.Random (randomRIO)
13import qualified Streamly.Benchmark.Data.ArrayOps as Ops
15import Gauge
16import Streamly.Benchmark.Common hiding (benchPureSrc)
18#ifdef MEMORY_ARRAY
19import qualified GHC.Exts as GHC
20import Foreign.Storable (Storable(..))
21#endif
23#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
24import Control.DeepSeq (deepseq)
25#endif
27-------------------------------------------------------------------------------
28--
29-------------------------------------------------------------------------------
31#ifdef MEMORY_ARRAY
32-- Drain a source that generates a pure array
33{-# INLINE benchPureSrc #-}
34benchPureSrc ::
35 (NFData a, Storable a) => String -> (Int -> Ops.Stream a) -> Benchmark
36benchPureSrc name src = benchPure name src id
37#endif
39{-# INLINE benchIO #-}
40benchIO :: NFData b => String -> (Int -> IO a) -> (a -> b) -> Benchmark
41benchIO name src f = bench name $ nfIO $
42 randomRIO (1,1) >>= src >>= return . f
44-- Drain a source that generates an array in the IO monad
45{-# INLINE benchIOSrc #-}
46benchIOSrc ::
47#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
48 NFData a =>
49#endif
50#ifdef MEMORY_ARRAY
51 Storable a =>
52#endif
53 String -> (Int -> IO (Ops.Stream a)) -> Benchmark
54benchIOSrc name src = benchIO name src id
56{-# INLINE benchPureSink #-}
57benchPureSink :: NFData b => Int -> String -> (Ops.Stream Int -> b) -> Benchmark
58benchPureSink value name f = benchIO name (Ops.sourceIntFromTo value) f
60{-# INLINE benchIO' #-}
61benchIO' :: NFData b => String -> (Int -> IO a) -> (a -> IO b) -> Benchmark
62benchIO' name src f = bench name $ nfIO $
63 randomRIO (1,1) >>= src >>= f
65{-# INLINE benchIOSink #-}
66benchIOSink :: NFData b => Int -> String -> (Ops.Stream Int -> IO b) -> Benchmark
67benchIOSink value name f = benchIO' name (Ops.sourceIntFromTo value) f
69o_1_space_generation :: Int -> [Benchmark]
70o_1_space_generation value =
71 [ bgroup
72 "generation"
73 [ benchIOSrc "writeN . intFromTo" (Ops.sourceIntFromTo value)
74#ifndef DATA_SMALLARRAY
75 , benchIOSrc "write . intFromTo" (Ops.sourceIntFromToFromStream value)
76#endif
77 , benchIOSrc
78 "fromList . intFromTo"
79 (Ops.sourceIntFromToFromList value)
80 , benchIOSrc "writeN . unfoldr" (Ops.sourceUnfoldr value)
81 , benchIOSrc "writeN . fromList" (Ops.sourceFromList value)
82#ifdef MEMORY_ARRAY
83 , benchPureSrc "writeN . IsList.fromList" (Ops.sourceIsList value)
84 , benchPureSrc
85 "writeN . IsString.fromString"
86 (Ops.sourceIsString value)
87#endif
88#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
89#ifdef DATA_SMALLARRAY
90 , let testStr =
91 "fromListN " ++
92 show (value + 1) ++
93 "[1" ++ concat (replicate value ",1") ++ "]"
94#else
95 , let testStr = mkListString value
96#endif
97 in testStr `deepseq` (bench "read" $ nf Ops.readInstance testStr)
98#endif
99 , benchPureSink value "show" Ops.showInstance
100 ]
101 ]
103o_1_space_elimination :: Int -> [Benchmark]
104o_1_space_elimination value =
105 [ bgroup "elimination"
106 [ benchPureSink value "id" id
107 , benchPureSink value "==" Ops.eqInstance
108 , benchPureSink value "/=" Ops.eqInstanceNotEq
109 , benchPureSink value "<" Ops.ordInstance
110 , benchPureSink value "min" Ops.ordInstanceMin
111#ifdef MEMORY_ARRAY
112 -- length is used to check for foldr/build fusion
113 , benchPureSink value "length . IsList.toList" (length . GHC.toList)
114#endif
115 , benchIOSink value "foldl'" Ops.pureFoldl'
116 , benchIOSink value "read" Ops.unfoldReadDrain
117 , benchIOSink value "toStreamRev" Ops.toStreamRevDrain
118#if !defined(DATA_ARRAY_PRIM) && !defined(DATA_ARRAY_PRIM_PINNED)
119#ifdef DEVBUILD
120 , benchPureSink value "foldable/foldl'" Ops.foldableFoldl'
121 , benchPureSink value "foldable/sum" Ops.foldableSum
122#endif
123#endif
124 ]
125 ]
127o_1_space_transformation :: Int -> [Benchmark]
128o_1_space_transformation value =
129 [ bgroup "transformation"
130 [ benchIOSink value "scanl'" (Ops.scanl' value 1)
131 , benchIOSink value "scanl1'" (Ops.scanl1' value 1)
132 , benchIOSink value "map" (Ops.map value 1)
133 ]
134 ]
136o_1_space_transformationX4 :: Int -> [Benchmark]
137o_1_space_transformationX4 value =
138 [ bgroup "transformationX4"
139 [ benchIOSink value "scanl'" (Ops.scanl' value 4)
140 , benchIOSink value "scanl1'" (Ops.scanl1' value 4)
141 , benchIOSink value "map" (Ops.map value 4)
142 ]
143 ]
145moduleName :: String
146#ifdef DATA_SMALLARRAY
147moduleName = "Data.SmallArray"
148#elif defined(MEMORY_ARRAY)
149moduleName = "Memory.Array"
150#elif defined(DATA_ARRAY_PRIM)
151moduleName = "Data.Array.Prim"
152#elif defined(DATA_ARRAY_PRIM_PINNED)
153moduleName = "Data.Array.Prim.Pinnned"
154#else
155moduleName = "Data.Array"
156#endif
158#ifdef DATA_SMALLARRAY
159defStreamSize :: Int
160defStreamSize = 128
161#else
162defStreamSize :: Int
163defStreamSize = defaultStreamSize
164#endif
166main :: IO ()
167main = do
168 (value, cfg, benches) <- parseCLIOpts defStreamSize
169 value `seq` runMode (mode cfg) cfg benches (allBenchmarks value)
171 where
173 allBenchmarks size =
174 [ bgroup (o_1_space_prefix moduleName) $ concat
175 [ o_1_space_generation size
176 , o_1_space_elimination size
177 , o_1_space_transformation size
178 , o_1_space_transformationX4 size
179 ]
180 ]