2015-07-26 23:06 GMT+02:00 Joachim Breitner <mail@joachim-breitner.de>:
Hi,

Am Sonntag, den 26.07.2015, 22:50 +0200 schrieb Lennart Kolmodin:
> This trick relies so much on that the user's code has been inlined
> properly that it probably very rarely fires in a real application. It
> does wonders in the unrealistic micro benchmark, though :)

what is the name of the rule? Can you find it on this list:
https://gist.github.com/nomeata/071c1f87450cf668bbeb

The rules;
{-# RULES

"<$> to <*>" forall f g.
  (<$>) f g = returnG f <*> g

"readN/readN merge" forall n m f g.
  apG (readN n f) (readN m g) = readN (n+m) (\bs -> f bs $ g (B.unsafeDrop n bs))

"returnG/readN swap" [~1] forall f.
  returnG f = readN 0 (const f)

"readN 0/returnG swapback" [1] forall f.
  readN 0 f = returnG (f B.empty) #-}

From your list (all of stackage with -ddump-rule-firings? brilliant! :));
399 Rule fired: <$> to <*>
106 Rule fired: readN/readN merge
1373 Rule fired: returnG/readN swap
2351 Rule fired: readN 0/returnG swapback

The "readN/readN merge" rule is what gives the speedup, the other rules are needed just to get the code lined up for the merge rule to fire.
So it fired 106 times. That's not a lot. When compiling one of the binary benchmarks it fires 33 times.
It might fire less often than it could, because the "<$> to <*>" rule might not get to fire as often as it wants (just like the warning says).
But, I can't slap a INLINE or NOINLINE on <$> though, since it's not part of the binary library.
So even if it does fire for some program out there, I'm still inclined to remove the rules. It's a little bit too much black magic.

Lennart



Greetings,
Joachim

--
Joachim “nomeata” Breitner
  mail@joachim-breitner.dehttp://www.joachim-breitner.de/
  Jabber: nomeata@joachim-breitner.de  • GPG-Key: 0xF0FBF51F
  Debian Developer: nomeata@debian.org