on master help sign in
Fix performance for some ops
c042050Harendra Kumar
src/Streamly/Streams/Serial.hs+10−4
@@ -149,6 +149,9 @@ type StreamT = SerialT
149serially :: IsStream t => SerialT m a -> t m a
149serially :: IsStream t => SerialT m a -> t m a
150serially = adapt
150serially = adapt
151
151
152+consMSerial :: Monad m => m a -> SerialT m a -> SerialT m a
153+consMSerial m ms = fromStream $ K.consMStream m (toStream ms)
154+
152instance IsStream SerialT where
155instance IsStream SerialT where
153 toStream = getSerialT
156 toStream = getSerialT
154 fromStream = SerialT
157 fromStream = SerialT
@@ -156,12 +159,12 @@ instance IsStream SerialT where
156 {-# INLINE consM #-}
159 {-# INLINE consM #-}
157 {-# SPECIALIZE consM :: IO a -> SerialT IO a -> SerialT IO a #-}
160 {-# SPECIALIZE consM :: IO a -> SerialT IO a -> SerialT IO a #-}
158 consM :: Monad m => m a -> SerialT m a -> SerialT m a
161 consM :: Monad m => m a -> SerialT m a -> SerialT m a
159− consM = K.consMSerial
162+ consM = consMSerial
160
163
161 {-# INLINE (|:) #-}
164 {-# INLINE (|:) #-}
162 {-# SPECIALIZE (|:) :: IO a -> SerialT IO a -> SerialT IO a #-}
165 {-# SPECIALIZE (|:) :: IO a -> SerialT IO a -> SerialT IO a #-}
163 (|:) :: Monad m => m a -> SerialT m a -> SerialT m a
166 (|:) :: Monad m => m a -> SerialT m a -> SerialT m a
164− (|:) = K.consMSerial
167+ (|:) = consMSerial
165
168
166------------------------------------------------------------------------------
169------------------------------------------------------------------------------
167-- Monad
170-- Monad
@@ -267,6 +270,9 @@ wSerially = adapt
267interleaving :: IsStream t => WSerialT m a -> t m a
270interleaving :: IsStream t => WSerialT m a -> t m a
268interleaving = wSerially
271interleaving = wSerially
269
272
273+consMWSerial :: Monad m => m a -> WSerialT m a -> WSerialT m a
274+consMWSerial m ms = fromStream $ K.consMStream m (toStream ms)
275+
270instance IsStream WSerialT where
276instance IsStream WSerialT where
271 toStream = getWSerialT
277 toStream = getWSerialT
272 fromStream = WSerialT
278 fromStream = WSerialT
@@ -274,12 +280,12 @@ instance IsStream WSerialT where
274 {-# INLINE consM #-}
280 {-# INLINE consM #-}
275 {-# SPECIALIZE consM :: IO a -> WSerialT IO a -> WSerialT IO a #-}
281 {-# SPECIALIZE consM :: IO a -> WSerialT IO a -> WSerialT IO a #-}
276 consM :: Monad m => m a -> WSerialT m a -> WSerialT m a
282 consM :: Monad m => m a -> WSerialT m a -> WSerialT m a
277− consM = K.consMSerial
283+ consM = consMWSerial
278
284
279 {-# INLINE (|:) #-}
285 {-# INLINE (|:) #-}
280 {-# SPECIALIZE (|:) :: IO a -> WSerialT IO a -> WSerialT IO a #-}
286 {-# SPECIALIZE (|:) :: IO a -> WSerialT IO a -> WSerialT IO a #-}
281 (|:) :: Monad m => m a -> WSerialT m a -> WSerialT m a
287 (|:) :: Monad m => m a -> WSerialT m a -> WSerialT m a
282− (|:) = K.consMSerial
288+ (|:) = consMWSerial
283
289
284------------------------------------------------------------------------------
290------------------------------------------------------------------------------
285-- Semigroup
291-- Semigroup
src/Streamly/Streams/StreamD.hs+2−2
@@ -235,7 +235,7 @@ cons x (Stream step state) = Stream step1 Nothing
235-- Does not fuse, has the same performance as the StreamK version.
235-- Does not fuse, has the same performance as the StreamK version.
236{-# INLINE_NORMAL uncons #-}
236{-# INLINE_NORMAL uncons #-}
237uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
237uncons :: Monad m => Stream m a -> m (Maybe (a, Stream m a))
238−uncons (Stream step state) = go state
238+uncons (UnStream step state) = go state
239 where
239 where
240 go st = do
240 go st = do
241 r <- step defState st
241 r <- step defState st
@@ -575,7 +575,7 @@ head (Stream step state) = go state
575-- Does not fuse, has the same performance as the StreamK version.
575-- Does not fuse, has the same performance as the StreamK version.
576{-# INLINE_NORMAL tail #-}
576{-# INLINE_NORMAL tail #-}
577tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
577tail :: Monad m => Stream m a -> m (Maybe (Stream m a))
578−tail (Stream step state) = go state
578+tail (UnStream step state) = go state
579 where
579 where
580 go st = do
580 go st = do
581 r <- step defState st
581 r <- step defState st
src/Streamly/Streams/StreamK.hs+15−1
@@ -151,7 +151,7 @@ module Streamly.Streams.StreamK
151 , serial
151 , serial
152
152
153 -- * Utilities
153 -- * Utilities
154− , consMSerial
154+ , consMStream
155 , bindWith
155 , bindWith
156 , withLocal
156 , withLocal
157
157
@@ -197,6 +197,7 @@ infixr 5 `cons`
197-- @
197-- @
198--
198--
199-- @since 0.1.0
199-- @since 0.1.0
200+{-# INLINE cons #-}
200cons :: IsStream t => a -> t m a -> t m a
201cons :: IsStream t => a -> t m a -> t m a
201cons a r = mkStream $ \_ yld _ _ -> yld a r
202cons a r = mkStream $ \_ yld _ _ -> yld a r
202
203
@@ -210,6 +211,7 @@ infixr 5 .:
210-- @
211-- @
211--
212--
212-- @since 0.1.1
213-- @since 0.1.1
214+{-# INLINE (.:) #-}
213(.:) :: IsStream t => a -> t m a -> t m a
215(.:) :: IsStream t => a -> t m a -> t m a
214(.:) = cons
216(.:) = cons
215
217
@@ -269,6 +271,7 @@ unfoldrM step = go
269-- Special generation
271-- Special generation
270-------------------------------------------------------------------------------
272-------------------------------------------------------------------------------
271
273
274+{-# INLINE yield #-}
272yield :: IsStream t => a -> t m a
275yield :: IsStream t => a -> t m a
273yield a = mkStream $ \_ _ single _ -> single a
276yield a = mkStream $ \_ _ single _ -> single a
274
277
@@ -289,14 +292,17 @@ once = yieldM
289-- Generate an infinite stream by repeating a pure value.
292-- Generate an infinite stream by repeating a pure value.
290--
293--
291-- @since 0.4.0
294-- @since 0.4.0
295+{-# INLINE repeat #-}
292repeat :: IsStream t => a -> t m a
296repeat :: IsStream t => a -> t m a
293repeat a = let x = cons a x in x
297repeat a = let x = cons a x in x
294
298
299+{-# INLINE replicateM #-}
295replicateM :: (IsStream t, MonadAsync m) => Int -> m a -> t m a
300replicateM :: (IsStream t, MonadAsync m) => Int -> m a -> t m a
296replicateM n m = go n
301replicateM n m = go n
297 where
302 where
298 go cnt = if cnt <= 0 then nil else m |: go (cnt - 1)
303 go cnt = if cnt <= 0 then nil else m |: go (cnt - 1)
299
304
305+{-# INLINE replicate #-}
300replicate :: IsStream t => Int -> a -> t m a
306replicate :: IsStream t => Int -> a -> t m a
301replicate n a = go n
307replicate n a = go n
302 where
308 where
@@ -331,6 +337,7 @@ fromStreamK = fromStream
331-------------------------------------------------------------------------------
337-------------------------------------------------------------------------------
332
338
333-- | Lazy right associative fold.
339-- | Lazy right associative fold.
340+{-# INLINE foldr #-}
334foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b
341foldr :: (IsStream t, Monad m) => (a -> b -> b) -> b -> t m a -> m b
335foldr step acc m = go m
342foldr step acc m = go m
336 where
343 where
@@ -405,6 +412,7 @@ foldl' step begin = foldx step begin id
405
412
406-- XXX replace the recursive "go" with explicit continuations.
413-- XXX replace the recursive "go" with explicit continuations.
407-- | Like 'foldx', but with a monadic step function.
414-- | Like 'foldx', but with a monadic step function.
415+{-# INLINABLE foldxM #-}
408foldxM :: (IsStream t, Monad m)
416foldxM :: (IsStream t, Monad m)
409 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
417 => (x -> a -> m x) -> m x -> (x -> m b) -> t m a -> m b
410foldxM step begin done m = go begin m
418foldxM step begin done m = go begin m
@@ -416,6 +424,7 @@ foldxM step begin done m = go begin m
416 in foldStream defState yieldk single stop m1
424 in foldStream defState yieldk single stop m1
417
425
418-- | Like 'foldl'' but with a monadic step function.
426-- | Like 'foldl'' but with a monadic step function.
427+{-# INLINE foldlM' #-}
419foldlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> m b
428foldlM' :: (IsStream t, Monad m) => (b -> a -> m b) -> b -> t m a -> m b
420foldlM' step begin = foldxM step (return begin) return
429foldlM' step begin = foldxM step (return begin) return
421
430
@@ -494,6 +503,7 @@ notElem e m = go m
494 yieldk a r = if a == e then return False else go r
503 yieldk a r = if a == e then return False else go r
495 in foldStream defState yieldk single stop m1
504 in foldStream defState yieldk single stop m1
496
505
506+{-# INLINABLE all #-}
497all :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
507all :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
498all p m = go m
508all p m = go m
499 where
509 where
@@ -504,6 +514,7 @@ all p m = go m
504 | otherwise = return False
514 | otherwise = return False
505 in foldStream defState yieldk single (return True) m1
515 in foldStream defState yieldk single (return True) m1
506
516
517+{-# INLINABLE any #-}
507any :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
518any :: (IsStream t, Monad m) => (a -> Bool) -> t m a -> m Bool
508any p m = go m
519any p m = go m
509 where
520 where
@@ -741,6 +752,7 @@ takeWhile p m = go m
741 | otherwise = stp
752 | otherwise = stp
742 in foldStream st yieldk single stp m1
753 in foldStream st yieldk single stp m1
743
754
755+{-# INLINE drop #-}
744drop :: IsStream t => Int -> t m a -> t m a
756drop :: IsStream t => Int -> t m a -> t m a
745drop n m = go n m
757drop n m = go n m
746 where
758 where
@@ -874,6 +886,7 @@ zipWith f = go
874-- | Zip two streams serially using a monadic zipping function.
886-- | Zip two streams serially using a monadic zipping function.
875--
887--
876-- @since 0.1.0
888-- @since 0.1.0
889+{-# INLINABLE zipWithM #-}
877zipWithM :: (IsStream t, Monad m) => (a -> b -> m c) -> t m a -> t m b -> t m c
890zipWithM :: (IsStream t, Monad m) => (a -> b -> m c) -> t m a -> t m b -> t m c
878zipWithM f m1 m2 = go m1 m2
891zipWithM f m1 m2 = go m1 m2
879 where
892 where
@@ -974,6 +987,7 @@ _alt m1 m2 = mkStream $ \st yld sng stp ->
974-- MonadReader
987-- MonadReader
975------------------------------------------------------------------------------
988------------------------------------------------------------------------------
976
989
990+{-# INLINABLE withLocal #-}
977withLocal :: MonadReader r m => (r -> r) -> Stream m a -> Stream m a
991withLocal :: MonadReader r m => (r -> r) -> Stream m a -> Stream m a
978withLocal f m =
992withLocal f m =
979 mkStream $ \st yld sng stp ->
993 mkStream $ \st yld sng stp ->
src/Streamly/Streams/StreamK/Type.hs+7−6
@@ -44,7 +44,7 @@ module Streamly.Streams.StreamK.Type
44 , foldStreamSVar
44 , foldStreamSVar
45
45
46 -- instances
46 -- instances
47− , consMSerial
47+ , consMStream
48
48
49 , nil
49 , nil
50 , serial
50 , serial
@@ -184,6 +184,7 @@ adapt = fromStream . toStream
184--
184--
185-- | Build a stream from an 'SVar', a stop continuation, a singleton stream
185-- | Build a stream from an 'SVar', a stop continuation, a singleton stream
186-- continuation and a yield continuation.
186-- continuation and a yield continuation.
187+{-# INLINABLE mkStream #-}
187mkStream:: IsStream t
188mkStream:: IsStream t
188 => (forall r. State Stream m a
189 => (forall r. State Stream m a
189 -> (a -> t m a -> m r)
190 -> (a -> t m a -> m r)
@@ -279,9 +280,9 @@ foldStreamSVar sv st yld sng stp m =
279-- Instances
280-- Instances
280-------------------------------------------------------------------------------
281-------------------------------------------------------------------------------
281
282
282−{-# INLINE consMSerial #-}
283+{-# INLINE consMStream #-}
283−consMSerial :: (IsStream t, Monad m) => m a -> t m a -> t m a
284+consMStream :: (Monad m) => m a -> Stream m a -> Stream m a
284−consMSerial m r = mkStream $ \_ yld _ _ -> m >>= \a -> yld a r
285+consMStream m r = MkStream $ \_ yld _ _ -> m >>= \a -> yld a r
285
286
286-------------------------------------------------------------------------------
287-------------------------------------------------------------------------------
287-- IsStream Stream
288-- IsStream Stream
@@ -294,12 +295,12 @@ instance IsStream Stream where
294 {-# INLINE consM #-}
295 {-# INLINE consM #-}
295 {-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
296 {-# SPECIALIZE consM :: IO a -> Stream IO a -> Stream IO a #-}
296 consM :: Monad m => m a -> Stream m a -> Stream m a
297 consM :: Monad m => m a -> Stream m a -> Stream m a
297− consM = consMSerial
298+ consM = consMStream
298
299
299 {-# INLINE (|:) #-}
300 {-# INLINE (|:) #-}
300 {-# SPECIALIZE (|:) :: IO a -> Stream IO a -> Stream IO a #-}
301 {-# SPECIALIZE (|:) :: IO a -> Stream IO a -> Stream IO a #-}
301 (|:) :: Monad m => m a -> Stream m a -> Stream m a
302 (|:) :: Monad m => m a -> Stream m a -> Stream m a
302− (|:) = consMSerial
303+ (|:) = consMStream
303
304
304------------------------------------------------------------------------------
305------------------------------------------------------------------------------
305-- Semigroup
306-- Semigroup
src/Streamly/Streams/Zip.hs+11−4
@@ -106,6 +106,9 @@ zipSerially = K.adapt
106zipping :: IsStream t => ZipSerialM m a -> t m a
106zipping :: IsStream t => ZipSerialM m a -> t m a
107zipping = zipSerially
107zipping = zipSerially
108
108
109+consMZip :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
110+consMZip m ms = fromStream $ K.consMStream m (toStream ms)
111+
109instance IsStream ZipSerialM where
112instance IsStream ZipSerialM where
110 toStream = getZipSerialM
113 toStream = getZipSerialM
111 fromStream = ZipSerialM
114 fromStream = ZipSerialM
@@ -113,12 +116,12 @@ instance IsStream ZipSerialM where
113 {-# INLINE consM #-}
116 {-# INLINE consM #-}
114 {-# SPECIALIZE consM :: IO a -> ZipSerialM IO a -> ZipSerialM IO a #-}
117 {-# SPECIALIZE consM :: IO a -> ZipSerialM IO a -> ZipSerialM IO a #-}
115 consM :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
118 consM :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
116− consM = K.consMSerial
119+ consM = consMZip
117
120
118 {-# INLINE (|:) #-}
121 {-# INLINE (|:) #-}
119 {-# SPECIALIZE (|:) :: IO a -> ZipSerialM IO a -> ZipSerialM IO a #-}
122 {-# SPECIALIZE (|:) :: IO a -> ZipSerialM IO a -> ZipSerialM IO a #-}
120 (|:) :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
123 (|:) :: Monad m => m a -> ZipSerialM m a -> ZipSerialM m a
121− (|:) = K.consMSerial
124+ (|:) = consMZip
122
125
123LIST_INSTANCES(ZipSerialM)
126LIST_INSTANCES(ZipSerialM)
124
127
@@ -199,6 +202,10 @@ zipAsyncly = K.adapt
199{-# DEPRECATED zippingAsync "Please use zipAsyncly instead." #-}
202{-# DEPRECATED zippingAsync "Please use zipAsyncly instead." #-}
200zippingAsync :: IsStream t => ZipAsyncM m a -> t m a
203zippingAsync :: IsStream t => ZipAsyncM m a -> t m a
201zippingAsync = zipAsyncly
204zippingAsync = zipAsyncly
205+
206+consMZipAsync :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
207+consMZipAsync m ms = fromStream $ K.consMStream m (toStream ms)
208+
202instance IsStream ZipAsyncM where
209instance IsStream ZipAsyncM where
203 toStream = getZipAsyncM
210 toStream = getZipAsyncM
204 fromStream = ZipAsyncM
211 fromStream = ZipAsyncM
@@ -206,12 +213,12 @@ instance IsStream ZipAsyncM where
206 {-# INLINE consM #-}
213 {-# INLINE consM #-}
207 {-# SPECIALIZE consM :: IO a -> ZipAsyncM IO a -> ZipAsyncM IO a #-}
214 {-# SPECIALIZE consM :: IO a -> ZipAsyncM IO a -> ZipAsyncM IO a #-}
208 consM :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
215 consM :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
209− consM = K.consMSerial
216+ consM = consMZipAsync
210
217
211 {-# INLINE (|:) #-}
218 {-# INLINE (|:) #-}
212 {-# SPECIALIZE (|:) :: IO a -> ZipAsyncM IO a -> ZipAsyncM IO a #-}
219 {-# SPECIALIZE (|:) :: IO a -> ZipAsyncM IO a -> ZipAsyncM IO a #-}
213 (|:) :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
220 (|:) :: Monad m => m a -> ZipAsyncM m a -> ZipAsyncM m a
214− (|:) = K.consMSerial
221+ (|:) = consMZipAsync
215
222
216instance Monad m => Functor (ZipAsyncM m) where
223instance Monad m => Functor (ZipAsyncM m) where
217 fmap = map
224 fmap = map