@@ -36,7 +36,7 @@ import Prelude
36 (Monad, String, Int, (+), ($), (.), return, even, (>), (<=), (==), (>=),
36 (Monad, String, Int, (+), ($), (.), return, even, (>), (<=), (==), (>=),
37 subtract, undefined, Maybe(..), Bool, not, (>>=), curry,
37 subtract, undefined, Maybe(..), Bool, not, (>>=), curry,
38 maxBound, div, IO, compare, Double, fromIntegral, Integer, (<$>),
38 maxBound, div, IO, compare, Double, fromIntegral, Integer, (<$>),
39− (<*>), flip)
39+ (<*>), flip, sqrt, round, (*), seq)
40import qualified Prelude as P
40import qualified Prelude as P
41import qualified Data.Foldable as F
41import qualified Data.Foldable as F
42import qualified GHC.Exts as GHC
42import qualified GHC.Exts as GHC
@@ -48,7 +48,22 @@ import Test.Inspection
48import qualified Streamly.Internal.Data.Stream.StreamD as D
48import qualified Streamly.Internal.Data.Stream.StreamD as D
51−import Streamly (SerialT, IsStream, wSerially, zipSerially, serially)
51+import Streamly
52import qualified Streamly as S hiding (runStream)
67import qualified Streamly as S hiding (runStream)
53import qualified Streamly.Prelude as S
68import qualified Streamly.Prelude as S
54import qualified Streamly.Internal.Prelude as Internal
69import qualified Streamly.Internal.Prelude as Internal
@@ -1289,9 +1304,25 @@ benchPureSinkIO
1289benchPureSinkIO value name f =
1304benchPureSinkIO value name f =
1290 bench name $ nfIO $ randomRIO (1, 1) >>= f . sourceUnfoldr value
1305 bench name $ nfIO $ randomRIO (1, 1) >>= f . sourceUnfoldr value
1307+{-# INLINE benchIO #-}
1292benchIO :: (NFData b) => String -> (Int -> IO b) -> Benchmark
1308benchIO :: (NFData b) => String -> (Int -> IO b) -> Benchmark
1293benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
1309benchIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
1311+-- | Takes a source, and uses it with a default drain/fold method.
1312+{-# INLINE benchSrcIO #-}
1314+ :: (t IO a -> SerialT IO a)
1319+ = bench name $ nfIO $ randomRIO (1,1) >>= toNull t . f
1321+{-# INLINE benchMonadicSrcIO #-}
1322+benchMonadicSrcIO :: String -> (Int -> IO ()) -> Benchmark
1323+benchMonadicSrcIO name f = bench name $ nfIO $ randomRIO (1,1) >>= f
1295-------------------------------------------------------------------------------
1326-------------------------------------------------------------------------------
1296-- Serial : O(1) Space
1327-- Serial : O(1) Space
1297-------------------------------------------------------------------------------
1328-------------------------------------------------------------------------------
@@ -2192,3 +2223,264 @@ o_n_stack_serial_iterated value =
2227+o_1_space_async_generation :: Int -> [Benchmark]
2228+o_1_space_async_generation value =
2233+ [ benchSrcIO asyncly "unfoldr" (sourceUnfoldr value)
2234+ , benchSrcIO asyncly "unfoldrM" (sourceUnfoldrM value)
2235+ , benchSrcIO asyncly "fromFoldable" (sourceFromFoldable value)
2236+ , benchSrcIO asyncly "fromFoldableM" (sourceFromFoldableM value)
2239+ "unfoldrM maxThreads 1"
2240+ (maxThreads 1 . sourceUnfoldrM value)
2243+ "unfoldrM maxBuffer 1 (x/10 ops)"
2244+ (maxBuffer 1 . sourceUnfoldrMN (value `div` 10))
2249+o_1_space_async_concatFoldable :: Int -> [Benchmark]
2250+o_1_space_async_concatFoldable value =
2255+ [ benchSrcIO asyncly "foldMapWith" (sourceFoldMapWith value)
2259+ (sourceFoldMapWithM value)
2260+ , benchSrcIO asyncly "foldMapM" (sourceFoldMapM value)
2266+o_1_space_async_concatMap :: Int -> [Benchmark]
2267+o_1_space_async_concatMap value =
2273+ [ benchMonadicSrcIO
2274+ "concatMapWith (2,x/2)"
2275+ (concatStreamsWith async 2 (value `div` 2))
2276+ , benchMonadicSrcIO
2277+ "concatMapWith (sqrt x,sqrt x)"
2278+ (concatStreamsWith async value2 value2)
2279+ , benchMonadicSrcIO
2280+ "concatMapWith (sqrt x * 2,sqrt x / 2)"
2281+ (concatStreamsWith async (value2 * 2) (value2 `div` 2))
2286+ value2 = round $ sqrt $ (fromIntegral value :: Double)
2289+o_1_space_async_transformation :: Int -> [Benchmark]
2290+o_1_space_async_transformation value =
2295+ [ benchIOSink value "map" $ map' asyncly 1
2296+ , benchIOSink value "fmap" $ fmap' asyncly 1
2297+ , benchIOSink value "mapM" $ mapM asyncly 1
2302+o_1_space_wAsync_generation :: Int -> [Benchmark]
2303+o_1_space_wAsync_generation value =
2308+ [ benchSrcIO wAsyncly "unfoldr" (sourceUnfoldr value)
2309+ , benchSrcIO wAsyncly "unfoldrM" (sourceUnfoldrM value)
2310+ , benchSrcIO wAsyncly "fromFoldable" (sourceFromFoldable value)
2314+ (sourceFromFoldableM value)
2317+ "unfoldrM maxThreads 1"
2318+ (maxThreads 1 . sourceUnfoldrM value)
2321+ "unfoldrM maxBuffer 1 (x/10 ops)"
2322+ (maxBuffer 1 . sourceUnfoldrMN (value `div` 10))
2327+o_1_space_wAsync_concatFoldable :: Int -> [Benchmark]
2328+o_1_space_wAsync_concatFoldable value =
2333+ [ benchSrcIO wAsyncly "foldMapWith" (sourceFoldMapWith value)
2334+ , benchSrcIO wAsyncly "foldMapWithM" (sourceFoldMapWithM value)
2335+ , benchSrcIO wAsyncly "foldMapM" (sourceFoldMapM value)
2340+-- When we merge streams using wAsync the size of the queue increases
2341+-- slowly because of the binary composition adding just one more item
2342+-- to the work queue only after every scheduling pass through the
2345+-- We should see the memory consumption increasing slowly if these
2346+-- benchmarks are left to run on infinite number of streams of infinite
2348+o_1_space_wAsync_concatMap :: Int -> [Benchmark]
2349+o_1_space_wAsync_concatMap value =
2353+ [ benchMonadicSrcIO
2354+ "concatMapWith (2,x/2)"
2355+ (concatStreamsWith wAsync 2 (value `div` 2))
2356+ , benchMonadicSrcIO
2357+ "concatMapWith (sqrt x,sqrt x)"
2358+ (concatStreamsWith wAsync value2 value2)
2359+ , benchMonadicSrcIO
2360+ "concatMapWith (sqrt x * 2,sqrt x / 2)"
2361+ (concatStreamsWith wAsync (value2 * 2) (value2 `div` 2))
2365+ value2 = round $ sqrt $ (fromIntegral value :: Double)
2368+o_1_space_wAsync_transformation :: Int -> [Benchmark]
2369+o_1_space_wAsync_transformation value =
2374+ [ benchIOSink value "map" $ map' wAsyncly 1
2375+ , benchIOSink value "fmap" $ fmap' wAsyncly 1
2376+ , benchIOSink value "mapM" $ mapM wAsyncly 1
2381+-- unfoldr and fromFoldable are always serial and therefore the same for
2382+-- all stream types. They can be removed to reduce the number of benchmarks.
2383+o_1_space_ahead_generation :: Int -> [Benchmark]
2384+o_1_space_ahead_generation value =
2389+ [ benchSrcIO aheadly "unfoldr" (sourceUnfoldr value)
2390+ , benchSrcIO aheadly "unfoldrM" (sourceUnfoldrM value)
2391+-- , benchSrcIO aheadly "fromFoldable" (sourceFromFoldable value)
2395+ (sourceFromFoldableM value)
2398+ "unfoldrM maxThreads 1"
2399+ (maxThreads 1 . sourceUnfoldrM value)
2402+ "unfoldrM maxBuffer 1 (x/10 ops)"
2403+ (maxBuffer 1 . sourceUnfoldrMN (value `div` 10))
2408+o_1_space_ahead_concatFoldable :: Int -> [Benchmark]
2409+o_1_space_ahead_concatFoldable value =
2414+ [ benchSrcIO aheadly "foldMapWith" (sourceFoldMapWith value)
2415+ , benchSrcIO aheadly "foldMapWithM" (sourceFoldMapWithM value)
2416+ , benchSrcIO aheadly "foldMapM" (sourceFoldMapM value)
2421+o_1_space_ahead_concatMap :: Int -> [Benchmark]
2422+o_1_space_ahead_concatMap value =
2426+ [ benchMonadicSrcIO
2427+ "concatMapWith (2,x/2)"
2428+ (concatStreamsWith ahead 2 (value `div` 2))
2429+ , benchMonadicSrcIO
2430+ "concatMapWith (sqrt x,sqrt x)"
2431+ (concatStreamsWith ahead value2 value2)
2432+ , benchMonadicSrcIO
2433+ "concatMapWith (sqrt x * 2,sqrt x / 2)"
2434+ (concatStreamsWith ahead (value2 * 2) (value2 `div` 2))
2438+ value2 = round $ sqrt $ (fromIntegral value :: Double)
2441+o_1_space_ahead_transformation :: Int -> [Benchmark]
2442+o_1_space_ahead_transformation value =
2447+ [ benchIOSink value "map" $ map' aheadly 1
2448+ , benchIOSink value "fmap" $ fmap' aheadly 1
2449+ , benchIOSink value "mapM" $ mapM aheadly 1
2454+o_1_space_async_zip :: Int -> [Benchmark]
2455+o_1_space_async_zip value =
2463+ (zipAsync (value `div` 2))
2466+ "zipAsyncM (2,x/2)"
2467+ (zipAsyncM (value `div` 2))
2470+ "zipAsyncAp (2,x/2)"
2471+ (zipAsyncAp (value `div` 2))
2472+ , benchIOSink value "fmap zipAsyncly" $ fmap' S.zipAsyncly 1
2475+ "mergeAsyncBy (2,x/2)"
2476+ (mergeAsyncBy (value `div` 2))
2479+ "mergeAsyncByM (2,x/2)"
2480+ (mergeAsyncByM (value `div` 2))
2481+ -- Parallel stages in a pipeline
2482+ , benchIOSink value "parAppMap" parAppMap
2483+ , benchIOSink value "parAppSum" parAppSum