on master help sign in
Seperate folds from Prelude in benchmarks.
commit18c903f5c4421522a6425bae08fccd136fa78f05 authoradithyaov <adithya@composewell.com> dateTue 17 Mar 2020, 22:10 (7 years ago) parent62bb140
6 files changed+215−139
benchmark/Streamly/Benchmark/Prelude/Serial/O_1_Space.hs+1 benchmark/Streamly/Benchmark/Prelude/Serial/O_n_Heap.hs+2 benchmark/lib/Streamly/Benchmark/Data/Fold.hs+210 benchmark/lib/Streamly/Benchmark/Prelude.hs−139 benchmark/streamly-benchmarks.cabal+1 streamly.cabal+1
benchmark/Streamly/Benchmark/Prelude/Serial/O_1_Space.hs+1
@@ -7,6 +7,7 @@
77
88import Streamly.Benchmark.Common
99import Streamly.Benchmark.Prelude
10+import Streamly.Benchmark.Data.Fold
1011
1112import Gauge
1213
benchmark/Streamly/Benchmark/Prelude/Serial/O_n_Heap.hs+2
@@ -7,6 +7,7 @@
77
88import Streamly.Benchmark.Common
99import Streamly.Benchmark.Prelude
10+import Streamly.Benchmark.Data.Fold
1011
1112import Gauge
1213
@@ -27,4 +28,5 @@ main = do
2728 concat
2829 [ o_n_heap_serial_foldl size
2930 , o_n_heap_serial_buffering size
31+ , o_n_heap_serial_folds size
3032 ]
benchmark/lib/Streamly/Benchmark/Data/Fold.hsnew file+210
@@ -0,0 +1,210 @@
1+-- |
2+-- Module : Streamly.Benchmark.Data.Fold
3+-- Copyright : (c) 2018 Composewell
4+--
5+-- License : MIT
6+-- Maintainer : streamly@composewell.com
7+
8+{-# LANGUAGE FlexibleContexts #-}
9+
10+module Streamly.Benchmark.Data.Fold
11+ ( o_1_space_serial_folds
12+ , o_1_space_serial_foldsTransforms
13+ , o_1_space_serial_foldsCompositions
14+ , o_n_heap_serial_folds
15+ ) where
16+
17+import Control.DeepSeq (NFData(..))
18+import Data.Monoid (Last(..))
19+
20+import System.Random (randomRIO)
21+import Prelude (IO, Int, Double, String, (>), (<*>), (<$>), (+), ($),
22+ (<=), Monad(..), (==), Maybe(..), (.), fromIntegral,
23+ compare, (>=))
24+
25+import qualified Streamly as S hiding (runStream)
26+import qualified Streamly.Prelude as S
27+import qualified Streamly.Internal.Data.Fold as FL
28+import qualified Streamly.Internal.Data.Pipe as Pipe
29+
30+import qualified Streamly.Internal.Data.Sink as Sink
31+
32+import qualified Streamly.Memory.Array as A
33+import qualified Streamly.Internal.Memory.Array as IA
34+import qualified Streamly.Internal.Data.Fold as IFL
35+import qualified Streamly.Internal.Prelude as IP
36+
37+import Gauge
38+import Streamly hiding (runStream)
39+
40+-- We need a monadic bind here to make sure that the function f does not get
41+-- completely optimized out by the compiler in some cases.
42+
43+{-# INLINE sourceUnfoldrM #-}
44+sourceUnfoldrM :: (S.IsStream t, S.MonadAsync m) => Int -> Int -> t m Int
45+sourceUnfoldrM value n = S.unfoldrM step n
46+ where
47+ step cnt =
48+ if cnt > n + value
49+ then return Nothing
50+ else return (Just (cnt, cnt + 1))
51+
52+{-# INLINE source #-}
53+source :: (S.MonadAsync m, S.IsStream t) => Int -> Int -> t m Int
54+source = sourceUnfoldrM
55+
56+-- | Takes a fold method, and uses it with a default source.
57+{-# INLINE benchIOSink #-}
58+benchIOSink
59+ :: (IsStream t, NFData b)
60+ => Int -> String -> (t IO Int -> IO b) -> Benchmark
61+benchIOSink value name f = bench name $ nfIO $ randomRIO (1,1) >>= f . source value
62+
63+-------------------------------------------------------------------------------
64+-- Stream folds
65+-------------------------------------------------------------------------------
66+
67+o_1_space_serial_folds :: Int -> [Benchmark]
68+o_1_space_serial_folds value =
69+ [ bgroup
70+ "serially"
71+ [ bgroup
72+ "folds"
73+ [ benchIOSink value "drain" (S.fold FL.drain)
74+ , benchIOSink value "drainN" (S.fold (IFL.drainN value))
75+ , benchIOSink
76+ value
77+ "drainWhileTrue"
78+ (S.fold (IFL.drainWhile $ (<=) (value + 1)))
79+ , benchIOSink
80+ value
81+ "drainWhileFalse"
82+ (S.fold (IFL.drainWhile $ (>=) (value + 1)))
83+ , benchIOSink value "sink" (S.fold $ Sink.toFold Sink.drain)
84+ , benchIOSink value "last" (S.fold FL.last)
85+ , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
86+ , benchIOSink value "lastN.10" (S.fold (IA.lastN 10))
87+ , benchIOSink value "length" (S.fold FL.length)
88+ , benchIOSink value "sum" (S.fold FL.sum)
89+ , benchIOSink value "product" (S.fold FL.product)
90+ , benchIOSink value "maximumBy" (S.fold (FL.maximumBy compare))
91+ , benchIOSink value "maximum" (S.fold FL.maximum)
92+ , benchIOSink value "minimumBy" (S.fold (FL.minimumBy compare))
93+ , benchIOSink value "minimum" (S.fold FL.minimum)
94+ , benchIOSink
95+ value
96+ "mean"
97+ (\s ->
98+ S.fold
99+ FL.mean
100+ (S.map (fromIntegral :: Int -> Double) s))
101+ , benchIOSink
102+ value
103+ "variance"
104+ (\s ->
105+ S.fold
106+ FL.variance
107+ (S.map (fromIntegral :: Int -> Double) s))
108+ , benchIOSink
109+ value
110+ "stdDev"
111+ (\s ->
112+ S.fold
113+ FL.stdDev
114+ (S.map (fromIntegral :: Int -> Double) s))
115+ , benchIOSink
116+ value
117+ "mconcat"
118+ (S.fold FL.mconcat . (S.map (Last . Just)))
119+ , benchIOSink
120+ value
121+ "foldMap"
122+ (S.fold (FL.foldMap (Last . Just)))
123+ , benchIOSink value "index" (S.fold (FL.index (value + 1)))
124+ , benchIOSink value "head" (S.fold FL.head)
125+ , benchIOSink value "find" (S.fold (FL.find (== (value + 1))))
126+ , benchIOSink
127+ value
128+ "findIndex"
129+ (S.fold (FL.findIndex (== (value + 1))))
130+ , benchIOSink
131+ value
132+ "elemIndex"
133+ (S.fold (FL.elemIndex (value + 1)))
134+ , benchIOSink value "null" (S.fold FL.null)
135+ , benchIOSink value "elem" (S.fold (FL.elem (value + 1)))
136+ , benchIOSink value "notElem" (S.fold (FL.notElem (value + 1)))
137+ , benchIOSink value "all" (S.fold (FL.all (<= (value + 1))))
138+ , benchIOSink value "any" (S.fold (FL.any (> (value + 1))))
139+ , benchIOSink
140+ value
141+ "and"
142+ (\s -> S.fold FL.and (S.map (<= (value + 1)) s))
143+ , benchIOSink
144+ value
145+ "or"
146+ (\s -> S.fold FL.or (S.map (> (value + 1)) s))
147+ ]
148+ ]
149+ ]
150+
151+
152+o_1_space_serial_foldsTransforms :: Int -> [Benchmark]
153+o_1_space_serial_foldsTransforms value =
154+ [ bgroup
155+ "serially"
156+ [ bgroup
157+ "folds-transforms"
158+ [ benchIOSink value "drain" (S.fold FL.drain)
159+ , benchIOSink value "lmap" (S.fold (IFL.lmap (+ 1) FL.drain))
160+ , benchIOSink
161+ value
162+ "pipe-mapM"
163+ (S.fold
164+ (IFL.transform
165+ (Pipe.mapM (\x -> return $ x + 1))
166+ FL.drain))
167+ ]
168+ ]
169+ ]
170+
171+
172+o_1_space_serial_foldsCompositions :: Int -> [Benchmark]
173+o_1_space_serial_foldsCompositions value =
174+ [ bgroup
175+ "serially"
176+ [ bgroup
177+ "folds-compositions" -- Applicative
178+ [ benchIOSink
179+ value
180+ "all,any"
181+ (S.fold
182+ ((,) <$> FL.all (<= (value + 1)) <*>
183+ FL.any (> (value + 1))))
184+ , benchIOSink
185+ value
186+ "sum,length"
187+ (S.fold ((,) <$> FL.sum <*> FL.length))
188+ ]
189+ ]
190+ ]
191+
192+
193+o_n_heap_serial_folds :: Int -> [Benchmark]
194+o_n_heap_serial_folds value =
195+ [ bgroup
196+ "serially"
197+ [ bgroup
198+ "foldl"
199+ -- Left folds for building a structure are inherently non-streaming
200+ -- as the structure cannot be lazily consumed until fully built.
201+ [ benchIOSink value "toStream" (S.fold IP.toStream)
202+ , benchIOSink value "toStreamRev" (S.fold IP.toStreamRev)
203+ , benchIOSink value "toList" (S.fold FL.toList)
204+ , benchIOSink value "toListRevF" (S.fold IFL.toListRevF)
205+ -- Converting the stream to an array
206+ , benchIOSink value "lastN.Max" (S.fold (IA.lastN (value + 1)))
207+ , benchIOSink value "writeN" (S.fold (A.writeN value))
208+ ]
209+ ]
210+ ]
benchmark/lib/Streamly/Benchmark/Prelude.hs−139
@@ -27,10 +27,7 @@ module Streamly.Benchmark.Prelude
2727 , o_1_space_serial_foldable
2828 , o_1_space_serial_generation
2929 , o_1_space_serial_elimination
30− , o_1_space_serial_folds
3130 , o_1_space_serial_foldMultiStream
32− , o_1_space_serial_foldsTransforms
33− , o_1_space_serial_foldsCompositions
3431 , o_1_space_serial_pipes
3532 , o_1_space_serial_pipesX4
3633 , o_1_space_serial_transformer
@@ -102,7 +99,6 @@ import Control.Monad.IO.Class (MonadIO(..))
10299import Control.Monad.State.Strict (StateT, get, put)
103100import Data.Functor.Identity (Identity, runIdentity)
104101import Data.IORef (newIORef, modifyIORef')
105−import Data.Monoid (Last(..))
106102import GHC.Generics (Generic)
107103import System.Random (randomRIO)
108104import Prelude
@@ -130,11 +126,6 @@ import qualified Streamly.Internal.Data.Pipe as Pipe
130126import qualified Streamly.Internal.Data.Stream.Parallel as Par
131127import Streamly.Internal.Data.Time.Units
132128
133−import qualified Streamly.Internal.Data.Sink as Sink
134−
135−import qualified Streamly.Memory.Array as A
136−import qualified Streamly.Internal.Memory.Array as IA
137−import qualified Streamly.Internal.Data.Fold as IFL
138129import qualified Streamly.Internal.Prelude as IP
139130
140131import qualified NestedOps as Nested
@@ -1760,90 +1751,6 @@ o_1_space_serial_elimination value =
17601751 ]
17611752 ]
17621753
1763−o_1_space_serial_folds :: Int -> [Benchmark]
1764−o_1_space_serial_folds value =
1765− [ bgroup
1766− "serially"
1767− [ bgroup
1768− "folds"
1769− [ benchIOSink value "drain" (S.fold FL.drain)
1770− , benchIOSink value "drainN" (S.fold (IFL.drainN value))
1771− , benchIOSink
1772− value
1773− "drainWhileTrue"
1774− (S.fold (IFL.drainWhile $ (<=) (value + 1)))
1775− , benchIOSink
1776− value
1777− "drainWhileFalse"
1778− (S.fold (IFL.drainWhile $ (>=) (value + 1)))
1779− , benchIOSink value "sink" (S.fold $ Sink.toFold Sink.drain)
1780− , benchIOSink value "last" (S.fold FL.last)
1781− , benchIOSink value "lastN.1" (S.fold (IA.lastN 1))
1782− , benchIOSink value "lastN.10" (S.fold (IA.lastN 10))
1783− , benchIOSink value "length" (S.fold FL.length)
1784− , benchIOSink value "sum" (S.fold FL.sum)
1785− , benchIOSink value "product" (S.fold FL.product)
1786− , benchIOSink value "maximumBy" (S.fold (FL.maximumBy compare))
1787− , benchIOSink value "maximum" (S.fold FL.maximum)
1788− , benchIOSink value "minimumBy" (S.fold (FL.minimumBy compare))
1789− , benchIOSink value "minimum" (S.fold FL.minimum)
1790− , benchIOSink
1791− value
1792− "mean"
1793− (\s ->
1794− S.fold
1795− FL.mean
1796− (S.map (fromIntegral :: Int -> Double) s))
1797− , benchIOSink
1798− value
1799− "variance"
1800− (\s ->
1801− S.fold
1802− FL.variance
1803− (S.map (fromIntegral :: Int -> Double) s))
1804− , benchIOSink
1805− value
1806− "stdDev"
1807− (\s ->
1808− S.fold
1809− FL.stdDev
1810− (S.map (fromIntegral :: Int -> Double) s))
1811− , benchIOSink
1812− value
1813− "mconcat"
1814− (S.fold FL.mconcat . (S.map (Last . Just)))
1815− , benchIOSink
1816− value
1817− "foldMap"
1818− (S.fold (FL.foldMap (Last . Just)))
1819− , benchIOSink value "index" (S.fold (FL.index (value + 1)))
1820− , benchIOSink value "head" (S.fold FL.head)
1821− , benchIOSink value "find" (S.fold (FL.find (== (value + 1))))
1822− , benchIOSink
1823− value
1824− "findIndex"
1825− (S.fold (FL.findIndex (== (value + 1))))
1826− , benchIOSink
1827− value
1828− "elemIndex"
1829− (S.fold (FL.elemIndex (value + 1)))
1830− , benchIOSink value "null" (S.fold FL.null)
1831− , benchIOSink value "elem" (S.fold (FL.elem (value + 1)))
1832− , benchIOSink value "notElem" (S.fold (FL.notElem (value + 1)))
1833− , benchIOSink value "all" (S.fold (FL.all (<= (value + 1))))
1834− , benchIOSink value "any" (S.fold (FL.any (> (value + 1))))
1835− , benchIOSink
1836− value
1837− "and"
1838− (\s -> S.fold FL.and (S.map (<= (value + 1)) s))
1839− , benchIOSink
1840− value
1841− "or"
1842− (\s -> S.fold FL.or (S.map (> (value + 1)) s))
1843− ]
1844− ]
1845− ]
1846−
18471754o_1_space_serial_foldMultiStream :: Int -> [Benchmark]
18481755o_1_space_serial_foldMultiStream value =
18491756 [ bgroup
@@ -1859,45 +1766,6 @@ o_1_space_serial_foldMultiStream value =
18591766 ]
18601767 ]
18611768
1862−o_1_space_serial_foldsTransforms :: Int -> [Benchmark]
1863−o_1_space_serial_foldsTransforms value =
1864− [ bgroup
1865− "serially"
1866− [ bgroup
1867− "folds-transforms"
1868− [ benchIOSink value "drain" (S.fold FL.drain)
1869− , benchIOSink value "lmap" (S.fold (IFL.lmap (+ 1) FL.drain))
1870− , benchIOSink
1871− value
1872− "pipe-mapM"
1873− (S.fold
1874− (IFL.transform
1875− (Pipe.mapM (\x -> return $ x + 1))
1876− FL.drain))
1877− ]
1878− ]
1879− ]
1880−
1881−o_1_space_serial_foldsCompositions :: Int -> [Benchmark]
1882−o_1_space_serial_foldsCompositions value =
1883− [ bgroup
1884− "serially"
1885− [ bgroup
1886− "folds-compositions" -- Applicative
1887− [ benchIOSink
1888− value
1889− "all,any"
1890− (S.fold
1891− ((,) <$> FL.all (<= (value + 1)) <*>
1892− FL.any (> (value + 1))))
1893− , benchIOSink
1894− value
1895− "sum,length"
1896− (S.fold ((,) <$> FL.sum <*> FL.length))
1897− ]
1898− ]
1899− ]
1900−
19011769o_1_space_serial_pipes :: Int -> [Benchmark]
19021770o_1_space_serial_pipes value =
19031771 [ bgroup
@@ -2389,13 +2257,6 @@ o_n_heap_serial_foldl value =
23892257 value
23902258 "foldlM'/build/Identity"
23912259 foldlM'Build
2392− , benchIOSink value "toStream" (S.fold IP.toStream)
2393− , benchIOSink value "toStreamRev" (S.fold IP.toStreamRev)
2394− , benchIOSink value "toList" (S.fold FL.toList)
2395− , benchIOSink value "toListRevF" (S.fold IFL.toListRevF)
2396− -- Converting the stream to an array
2397− , benchIOSink value "lastN.Max" (S.fold (IA.lastN (value + 1)))
2398− , benchIOSink value "writeN" (S.fold (A.writeN value))
23992260 -- Reversing/sorting a stream
24002261 , benchIOSink value "reverse" (reverse 1)
24012262 , benchIOSink value "reverse'" (reverse' 1)
benchmark/streamly-benchmarks.cabal+1
@@ -137,6 +137,7 @@ library lib-prelude
137137 hs-source-dirs: lib, .
138138 exposed-modules:
139139 Streamly.Benchmark.Prelude
140+ , Streamly.Benchmark.Data.Fold
140141 other-modules: Streamly.Benchmark.Common
141142 , NestedOps
142143 , NestedUnfoldOps
streamly.cabal+1
@@ -123,6 +123,7 @@ extra-source-files:
123123 benchmark/README.md
124124 benchmark/*.hs
125125 benchmark/lib/Streamly/Benchmark/*.hs
126+ benchmark/lib/Streamly/Benchmark/Data/*.hs
126127 benchmark/Streamly/Benchmark/Data/*.hs
127128 benchmark/Streamly/Benchmark/Data/Prim/*.hs
128129 benchmark/Streamly/Benchmark/Data/Stream/*.hs