<div dir="ltr">Thanks Mikolaj! I have seen some surprising behavior quite a few times recently and I was wondering whether GHC should do better. In one case I had to use SPECIALIZE very aggressively, in another version of the same code it worked well without that. I have been doing a lot of trial and error with the INLINE/NOINLINE pragmas to figure out what the right combination is. Sometimes it just feels like black magic, because I cannot find a rationale to explain the behavior. I am not sure if there are any more such problems lurking in, perhaps this is an area where some improvement looks possible.<div><br></div><div>-harendra</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 8 September 2017 at 17:10, Mikolaj Konarski <span dir="ltr"><<a href="mailto:mikolaj.konarski@gmail.com" target="_blank">mikolaj.konarski@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
<br>
I've had a similar problem that's been fixed in 8.2.1:<br>
<br>
<a href="https://ghc.haskell.org/trac/ghc/ticket/12603" rel="noreferrer" target="_blank">https://ghc.haskell.org/trac/<wbr>ghc/ticket/12603</a><br>
<br>
You can also use some extreme global flags, such as<br>
<br>
ghc-options: -fexpose-all-unfoldings -fspecialise-aggressively<br>
<br>
to get most the GHC subtlety and shyness out of the way<br>
when experimenting.<br>
<br>
Good luck<br>
Mikolaj<br>
<div><div class="h5"><br>
<br>
<br>
On Fri, Sep 8, 2017 at 11:21 AM, Harendra Kumar<br>
<<a href="mailto:harendra.kumar@gmail.com">harendra.kumar@gmail.com</a>> wrote:<br>
> Hi,<br>
><br>
> I have this code snippet for the bind implementation of a Monad:<br>
><br>
> AsyncT m >>= f = AsyncT $ \_ stp yld -><br>
> let run x = (runAsyncT x) Nothing stp yld<br>
> yield a _ Nothing = run $ f a<br>
> yield a _ (Just r) = run $ f a <> (r >>= f)<br>
> in m Nothing stp yield<br>
><br>
> I want to have multiple versions of this implementation parameterized by a<br>
> function, like this:<br>
><br>
> bindWith k (AsyncT m) f = AsyncT $ \_ stp yld -><br>
> let run x = (runAsyncT x) Nothing stp yld<br>
> yield a _ Nothing = run $ f a<br>
> yield a _ (Just r) = run $ f a `k` (bindWith k r f)<br>
> in m Nothing stp yield<br>
><br>
> And then the bind function becomes:<br>
><br>
> (>>=) = bindWith (<>)<br>
><br>
> But this leads to a performance degradation of more than 10%. inlining does<br>
> not help, I tried INLINE pragma as well as the "inline" GHC builtin. I<br>
> thought this should be a more or less straightforward replacement making the<br>
> second version equivalent to the first one. But apparently there is<br>
> something going on here that makes it perform worse.<br>
><br>
> I did not look at the core, stg or asm yet. Hoping someone can quickly<br>
> comment on it. Any ideas why is it so? Can this be worked around somehow?<br>
><br>
> Thanks,<br>
> Harendra<br>
><br>
</div></div>> ______________________________<wbr>_________________<br>
> ghc-devs mailing list<br>
> <a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/ghc-devs</a><br>
><br>
</blockquote></div><br></div>