Inline MC.try to fix perf for GHC-9

This commit is contained in:
Harendra Kumar 2021-06-18 22:46:32 +05:30
parent 49a4333edb
commit 67f851374c
2 changed files with 35 additions and 11 deletions

View File

@ -36,6 +36,8 @@ import Streamly.Benchmark.Common.Handle
#ifdef INSPECTION
import Test.Inspection
import qualified Streamly.Internal.Data.Stream.StreamD as D
#endif
-------------------------------------------------------------------------------
@ -48,6 +50,10 @@ readWriteOnExceptionStream inh devNull =
let readEx = S.onException (hClose inh) (S.unfold FH.read inh)
in S.fold (FH.write devNull) $ readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readWriteOnExceptionStream
#endif
-- | Send the file contents to /dev/null with exception handling
readWriteHandleExceptionStream :: Handle -> Handle -> IO ()
readWriteHandleExceptionStream inh devNull =
@ -55,12 +61,20 @@ readWriteHandleExceptionStream inh devNull =
readEx = S.handle handler (S.unfold FH.read inh)
in S.fold (FH.write devNull) $ readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readWriteHandleExceptionStream
#endif
-- | Send the file contents to /dev/null with exception handling
readWriteFinally_Stream :: Handle -> Handle -> IO ()
readWriteFinally_Stream inh devNull =
let readEx = IP.finally_ (hClose inh) (S.unfold FH.read inh)
in S.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readWriteFinally_Stream
#endif
readWriteFinallyStream :: Handle -> Handle -> IO ()
readWriteFinallyStream inh devNull =
let readEx = S.finally (hClose inh) (S.unfold FH.read inh)
@ -75,7 +89,6 @@ fromToBytesBracket_Stream inh devNull =
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'fromToBytesBracket_Stream
-- inspect $ 'fromToBytesBracketStream `hasNoType` ''Step
#endif
fromToBytesBracketStream :: Handle -> Handle -> IO ()
@ -91,16 +104,29 @@ readWriteBeforeAfterStream inh devNull =
$ IP.before (hPutChar devNull 'A') (S.unfold FH.read inh)
in S.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ 'readWriteBeforeAfterStream `hasNoType` ''D.Step
#endif
readWriteAfterStream :: Handle -> Handle -> IO ()
readWriteAfterStream inh devNull =
let readEx = IP.after (hClose inh) (S.unfold FH.read inh)
in S.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ 'readWriteAfterStream `hasNoType` ''D.Step
#endif
readWriteAfter_Stream :: Handle -> Handle -> IO ()
readWriteAfter_Stream inh devNull =
let readEx = IP.after_ (hClose inh) (S.unfold FH.read inh)
in S.fold (FH.write devNull) readEx
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readWriteAfter_Stream
inspect $ 'readWriteAfter_Stream `hasNoType` ''D.Step
#endif
o_1_space_copy_stream_exceptions :: BenchEnv -> [Benchmark]
o_1_space_copy_stream_exceptions env =
[ bgroup "exceptions"
@ -139,7 +165,6 @@ readChunksOnException inh devNull =
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readChunksOnException
-- inspect $ 'readChunksOnException `hasNoType` ''Step
#endif
-- | Send the file contents to /dev/null with exception handling
@ -150,7 +175,6 @@ readChunksBracket_ inh devNull =
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'readChunksBracket_
-- inspect $ 'readChunksBracket `hasNoType` ''Step
#endif
readChunksBracket :: Handle -> Handle -> IO ()
@ -185,7 +209,6 @@ toChunksBracket_ inh devNull =
#ifdef INSPECTION
inspect $ hasNoTypeClasses 'toChunksBracket_
-- inspect $ 'toChunksBracket `hasNoType` ''Step
#endif
toChunksBracket :: Handle -> Handle -> IO ()

View File

@ -29,6 +29,7 @@ import Control.Exception (Exception, SomeException, mask_)
import Control.Monad.Catch (MonadCatch)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.Control (MonadBaseControl, liftBaseOp_)
import GHC.Exts (inline)
import Streamly.Internal.Data.IOFinalizer
(newIOFinalizer, runIOFinalizer, clearingIOFinalizer)
@ -231,7 +232,7 @@ after action (Stream step state) = Stream step' Nothing
{-# INLINE_NORMAL onException #-}
onException :: MonadCatch m => m b -> Stream m a -> Stream m a
onException action str =
gbracket_ (return ()) MC.try return
gbracket_ (return ()) (inline MC.try) return
(\_ (e :: MC.SomeException) _ -> nilM (action >> MC.throwM e))
(\_ -> str)
@ -255,7 +256,7 @@ _onException action (Stream step state) = Stream step' state
bracket_ :: MonadCatch m
=> m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
bracket_ bef aft bet =
gbracket_ bef MC.try aft
gbracket_ bef (inline MC.try) aft
(\a (e :: SomeException) _ -> nilM (aft a >> MC.throwM e)) bet
-- | See 'Streamly.Internal.Data.Stream.IsStream.bracket'.
@ -264,7 +265,7 @@ bracket_ bef aft bet =
bracket :: (MonadAsync m, MonadCatch m)
=> m b -> (b -> m c) -> (b -> Stream m a) -> Stream m a
bracket bef aft bet =
gbracket bef MC.try aft
gbracket bef (inline MC.try) aft
(\a (e :: SomeException) _ -> aft a >> return (nilM (MC.throwM e))) bet
data BracketState s v = BracketInit | BracketRun s v
@ -285,7 +286,7 @@ _bracket bef aft bet = Stream step' BracketInit
-- here, otherwise we get huge perf degradation, see note in concatMap.
step' gst (BracketRun (UnStream step state) v) = do
-- res <- step gst state `MC.onException` aft v
res <- MC.try $ step gst state
res <- inline MC.try $ step gst state
case res of
Left (e :: SomeException) -> aft v >> MC.throwM e >> return Stop
Right r -> case r of
@ -313,7 +314,7 @@ finally action xs = bracket (return ()) (\_ -> action) (const xs)
ghandle :: (MonadCatch m, Exception e)
=> (e -> Stream m a -> Stream m a) -> Stream m a -> Stream m a
ghandle f str =
gbracket_ (return ()) MC.try return (\_ -> f) (\_ -> str)
gbracket_ (return ()) (inline MC.try) return (\_ -> f) (\_ -> str)
-- | See 'Streamly.Internal.Data.Stream.IsStream.handle'.
--
@ -321,7 +322,7 @@ ghandle f str =
handle :: (MonadCatch m, Exception e)
=> (e -> Stream m a) -> Stream m a -> Stream m a
handle f str =
gbracket_ (return ()) MC.try return (\_ e _ -> f e) (\_ -> str)
gbracket_ (return ()) (inline MC.try) return (\_ e _ -> f e) (\_ -> str)
-- | Alternate (custom) implementation of 'handle'.
--
@ -334,7 +335,7 @@ _handle f (Stream step state) = Stream step' (Left state)
{-# INLINE_LATE step' #-}
step' gst (Left st) = do
res <- MC.try $ step gst st
res <- inline MC.try $ step gst st
case res of
Left e -> return $ Skip $ Right (f e)
Right r -> case r of