Performance degradation when factoring out common code
Harendra Kumar
harendra.kumar at gmail.com
Fri Sep 8 09:21:09 UTC 2017
Hi,
I have this code snippet for the bind implementation of a Monad:
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
I want to have multiple versions of this implementation parameterized by a
function, like this:
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
And then the bind function becomes:
(>>=) = bindWith (<>)
But this leads to a performance degradation of more than 10%. inlining does
not help, I tried INLINE pragma as well as the "inline" GHC builtin. I
thought this should be a more or less straightforward replacement making
the second version equivalent to the first one. But apparently there is
something going on here that makes it perform worse.
I did not look at the core, stg or asm yet. Hoping someone can quickly
comment on it. Any ideas why is it so? Can this be worked around somehow?
Thanks,
Harendra
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20170908/d7c6a11f/attachment-0001.html>
More information about the ghc-devs
mailing list