[Haskell-cafe] Monad transformer performance - Request to review benchmarking code + results

Oliver Charles ollie at ocharles.org.uk
Sun Feb 5 23:24:23 UTC 2017


Saurabh Nanda <saurabhnanda at gmail.com> writes:

>> Why do you keep expecting the compiler to "be smart"? It's just shuffling
>> data around, any type of magic efficiency with Monadic computations
>> requires specific knowledge about monads, which is not something we encode
>> into the compiler. just saying "this should be obvious" is not very
>> productive.
>>
>
> Two reasons:
>
> * If inlining certain functions can give a boost to the performance, then
> is it unreasonable to expect the compiler to have better heuristics about
> when commonly occurring code patterns should be inlined? In this case
> monads and mtl being the commonly occurring code patterns.
>
> * At a broader level, the promise of writing pure functions was to be able
> to talk about 'intent', not 'implementation' -- the classic `map` vs `for
> loop` example. Additionally, pure functions give the compiler enough
> opportunity to optimise code. Both these higher level promises are being
> broken by this experience. Hence, I'm feeling "cheated"

Inlining can only happen if the code to be inlined is available. This
means explicitly marking things with {-# INLINE #-} or {-# INLINEABLE
#-} (or GHC seeing something as "small" and deciding it's worth putting
in the .hi file). If I give you "foo True" and tell you nothing more
about "foo" - how are you going to optimise that? That's essentially
what is happening - GHC has no more information so all it can do is just
call the function and hope for the best.

> Additionally, pure functions give the compiler enough
> opportunity to optimise code. Both these higher level promises are being
> broken by this experience. Hence, I'm feeling "cheated"

Certainly, but the benefits of purity are different. We use purity to
know that we can rewrite ASTs, introduce sharing, lift let-bindings up,
move case statements around, and so on. This is very different that
"understanding how monad transformers work". You still seem to be
suggesting that "it's obvious" a compiler should be able to optimise
this code, but without actually being able to inline the code and
unleash all of GHC's optimisations, I'm not sure what else the compiler
can do. It's just a black box otherwise.

Of course, it's a shame that {-# INLINE #-} is almost a requirement for
some types of performant code, but right now - it is what it is.

-- ocharles


More information about the Haskell-Cafe mailing list