Compiler is unable to INLINE as well as the programmer can manually
The test case is in this repo on the inlining-issue branch: https://github.com/harendra-kumar/ghc-perf/tree/inlining-issue.
Performance with manually inlining a function is more than 10% faster compared to factoring out code and using INLINE pragma.
stack bench for compiler inlined code
time 46.71 ms (45.53 ms .. 47.79 ms)
stack bench --flag ghc-perf:manual for manually inlined code
time 39.46 ms (38.92 ms .. 39.94 ms)
Here is the relevant code:
{-# INLINE bindWith #-}
bindWith
:: (forall c. AsyncT m c -> AsyncT m c -> AsyncT m c)
-> AsyncT m a
-> (a -> AsyncT m b)
-> AsyncT m b
bindWith k (AsyncT m) f = AsyncT $ \_ stp yld ->
let run x = (runAsyncT x) Nothing stp yld
yield a _ Nothing = run $ f a
yield a _ (Just r) = run $ f a `k` (bindWith k r f)
in m Nothing stp yield
instance Monad m => Monad (AsyncT m) where
return a = AsyncT $ \ctx _ yld -> yld a ctx Nothing
#ifdef MANUAL_INLINE
AsyncT m >>= f = AsyncT $ \_ stp yld ->
let run x = (runAsyncT x) Nothing stp yld
yield a _ Nothing = run $ f a
yield a _ (Just r) = run $ f a <> (r >>= f)
in m Nothing stp yield
#else
(>>=) = bindWith (<>)
#endif
I have seen this many times.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | mpickering |
| Operating system | |
| Architecture |