on master help sign in
inline the exception functions
e347812Harendra Kumar
src/Streamly/Prelude.hs+18
@@ -2227,19 +2227,31 @@ intercalate :: (IsStream t, MonadAsync m) => t m a -> t m a -> t m a
2227------------------------------------------------------------------------------
2227------------------------------------------------------------------------------
2228
2228
2229-- | Run a side effect before the stream yields its first element.
2229-- | Run a side effect before the stream yields its first element.
2230+--
2231+-- @since 0.7.0
2232+{-# INLINE before #-}
2230before :: (IsStream t, Monad m) => m b -> t m a -> t m a
2233before :: (IsStream t, Monad m) => m b -> t m a -> t m a
2231before action xs = D.fromStreamD $ D.before action $ D.toStreamD xs
2234before action xs = D.fromStreamD $ D.before action $ D.toStreamD xs
2232
2235
2233-- | Run a side effect whenever the stream stops normally.
2236-- | Run a side effect whenever the stream stops normally.
2237+--
2238+-- @since 0.7.0
2239+{-# INLINE after #-}
2234after :: (IsStream t, Monad m) => m b -> t m a -> t m a
2240after :: (IsStream t, Monad m) => m b -> t m a -> t m a
2235after action xs = D.fromStreamD $ D.after action $ D.toStreamD xs
2241after action xs = D.fromStreamD $ D.after action $ D.toStreamD xs
2236
2242
2237-- | Run a side effect whenever the stream aborts due to an exception.
2243-- | Run a side effect whenever the stream aborts due to an exception.
2244+--
2245+-- @since 0.7.0
2246+{-# INLINE onException #-}
2238onException :: (IsStream t, MonadCatch m) => m b -> t m a -> t m a
2247onException :: (IsStream t, MonadCatch m) => m b -> t m a -> t m a
2239onException action xs = D.fromStreamD $ D.onException action $ D.toStreamD xs
2248onException action xs = D.fromStreamD $ D.onException action $ D.toStreamD xs
2240
2249
2241-- | Run a side effect whenever the stream stops normally or aborts due to an
2250-- | Run a side effect whenever the stream stops normally or aborts due to an
2242-- exception.
2251-- exception.
2252+--
2253+-- @since 0.7.0
2254+{-# INLINE finally #-}
2243finally :: (IsStream t, MonadCatch m) => m b -> t m a -> t m a
2255finally :: (IsStream t, MonadCatch m) => m b -> t m a -> t m a
2244finally action xs = D.fromStreamD $ D.finally action $ D.toStreamD xs
2256finally action xs = D.fromStreamD $ D.finally action $ D.toStreamD xs
2245
2257
@@ -2247,6 +2259,9 @@ finally action xs = D.fromStreamD $ D.finally action $ D.toStreamD xs
2247-- generate a stream using the output, run the second action using the
2259-- generate a stream using the output, run the second action using the
2248-- remembered value as an argument whenever the stream ends normally or due to
2260-- remembered value as an argument whenever the stream ends normally or due to
2249-- an exception.
2261-- an exception.
2262+--
2263+-- @since 0.7.0
2264+{-# INLINE bracket #-}
2250bracket :: (IsStream t, MonadCatch m)
2265bracket :: (IsStream t, MonadCatch m)
2251 => m b -> (b -> m c) -> (b -> t m a) -> t m a
2266 => m b -> (b -> m c) -> (b -> t m a) -> t m a
2252bracket bef aft bet = D.fromStreamD $
2267bracket bef aft bet = D.fromStreamD $
@@ -2254,6 +2269,9 @@ bracket bef aft bet = D.fromStreamD $
2254
2269
2255-- | When evaluating a stream if an exception occurs, stream evaluation aborts
2270-- | When evaluating a stream if an exception occurs, stream evaluation aborts
2256-- and the specified exception handler is run with the exception as argument.
2271-- and the specified exception handler is run with the exception as argument.
2272+--
2273+-- @since 0.7.0
2274+{-# INLINE handle #-}
2257handle :: (IsStream t, MonadCatch m, Exception e)
2275handle :: (IsStream t, MonadCatch m, Exception e)
2258 => (e -> m a) -> t m a -> t m a
2276 => (e -> m a) -> t m a -> t m a
2259handle handler xs = D.fromStreamD $ D.handle handler $ D.toStreamD xs
2277handle handler xs = D.fromStreamD $ D.handle handler $ D.toStreamD xs
src/Streamly/Streams/StreamD.hs+22−1
@@ -1680,6 +1680,7 @@ fromStreamD = K.fromStream . toStreamK
1680------------------------------------------------------------------------------
1680------------------------------------------------------------------------------
1681
1681
1682-- | Run a side effect before the stream yields its first element.
1682-- | Run a side effect before the stream yields its first element.
1683+{-# INLINE_NORMAL before #-}
1683before :: Monad m => m b -> Stream m a -> Stream m a
1684before :: Monad m => m b -> Stream m a -> Stream m a
1684before action (Stream step state) = Stream step' Nothing
1685before action (Stream step state) = Stream step' Nothing
1685
1686
@@ -1696,6 +1697,7 @@ before action (Stream step state) = Stream step' Nothing
1696 Stop -> return Stop
1697 Stop -> return Stop
1697
1698
1698-- | Run a side effect whenever the stream stops normally.
1699-- | Run a side effect whenever the stream stops normally.
1700+{-# INLINE_NORMAL after #-}
1699after :: Monad m => m b -> Stream m a -> Stream m a
1701after :: Monad m => m b -> Stream m a -> Stream m a
1700after action (Stream step state) = Stream step' state
1702after action (Stream step state) = Stream step' state
1701
1703
@@ -1709,8 +1711,18 @@ after action (Stream step state) = Stream step' state
1709 Skip s -> return $ Skip s
1711 Skip s -> return $ Skip s
1710 Stop -> action >> return Stop
1712 Stop -> action >> return Stop
1711
1713
1714+-- XXX These combinators are expensive due to the call to
1715+-- onException/handle/try on each step. Therefore, they should called in an
1716+-- outer loop where we perform less iterations. For example, we cannot call
1717+-- them on each iteration in a char stream, instead we can call them when doing
1718+-- an IO on an array.
1719+--
1720+-- XXX For high performance error checks in busy streams we may need another
1721+-- Error constructor in step.
1722+--
1712-- | Run a side effect whenever the stream aborts due to an exception. The
1723-- | Run a side effect whenever the stream aborts due to an exception. The
1713-- exception is not caught simply rethrown.
1724-- exception is not caught simply rethrown.
1725+{-# INLINE_NORMAL onException #-}
1714onException :: MonadCatch m => m b -> Stream m a -> Stream m a
1726onException :: MonadCatch m => m b -> Stream m a -> Stream m a
1715onException action (Stream step state) = Stream step' state
1727onException action (Stream step state) = Stream step' state
1716
1728
@@ -1728,13 +1740,19 @@ onException action (Stream step state) = Stream step' state
1728--
1740--
1729-- | Run a side effect whenever the stream stops normally or aborts due to an
1741-- | Run a side effect whenever the stream stops normally or aborts due to an
1730-- exception.
1742-- exception.
1743+{-# INLINE finally #-}
1731finally :: MonadCatch m => m b -> Stream m a -> Stream m a
1744finally :: MonadCatch m => m b -> Stream m a -> Stream m a
1732finally action xs = after action $ onException action xs
1745finally action xs = after action $ onException action xs
1733
1746
1747+-- XXX bracket is like concatMap, it generates a stream and then flattens it.
1748+-- Like concatMap it has 10x worse performance compared to linear fused
1749+-- compositions.
1750+--
1734-- | Run the first action before the stream starts and remember its output,
1751-- | Run the first action before the stream starts and remember its output,
1735-- generate a stream using the output, run the second action using the
1752-- generate a stream using the output, run the second action using the
1736-- remembered value as an argument whenever the stream ends normally or due to
1753-- remembered value as an argument whenever the stream ends normally or due to
1737-- an exception.
1754-- an exception.
1755+{-# INLINE_NORMAL bracket #-}
1738bracket :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
1756bracket :: MonadCatch m => m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
1739bracket bef aft bet = Stream step' Nothing
1757bracket bef aft bet = Stream step' Nothing
1740
1758
@@ -1743,7 +1761,9 @@ bracket bef aft bet = Stream step' Nothing
1743 {-# INLINE_LATE step' #-}
1761 {-# INLINE_LATE step' #-}
1744 step' _ Nothing = bef >>= \x -> return (Skip (Just (bet x, x)))
1762 step' _ Nothing = bef >>= \x -> return (Skip (Just (bet x, x)))
1745
1763
1764+ -- NOTE: It is important to use UnStream instead of the Stream pattern
1765+ -- here, otherwise we get huge perf degradation, see note in concatMap.
1746− step' gst (Just (Stream step state, v)) = do
1766+ step' gst (Just (UnStream step state, v)) = do
1747 res <- step gst state `MC.onException` aft v
1767 res <- step gst state `MC.onException` aft v
1748 case res of
1768 case res of
1749 Yield x s -> return $ Yield x (Just (Stream step s, v))
1769 Yield x s -> return $ Yield x (Just (Stream step s, v))
@@ -1752,6 +1772,7 @@ bracket bef aft bet = Stream step' Nothing
1752
1772
1753-- | When evaluating a stream if an exception occurs, stream evaluation aborts
1773-- | When evaluating a stream if an exception occurs, stream evaluation aborts
1754-- and the specified exception handler is run with the exception as argument.
1774-- and the specified exception handler is run with the exception as argument.
1775+{-# INLINE_NORMAL handle #-}
1755handle :: (MonadCatch m, Exception e) => (e -> m a) -> Stream m a -> Stream m a
1776handle :: (MonadCatch m, Exception e) => (e -> m a) -> Stream m a -> Stream m a
1756handle f (Stream step state) = Stream step' (Just state)
1777handle f (Stream step state) = Stream step' (Just state)
1757
1778