[Haskell-cafe] transformers appears to benefit from more inline

34 views
Skip to first unread message

Oliver Charles

unread,
Jan 24, 2016, 1:21:55 PM1/24/16
to Haskell Cafe
Hi everyone,

I've recently been playing with a little mtl-like approach to streaming data, whereby I have a single type class - MonadYield - which can yield data, and then I use various implementations of this type class to implement operations. My usual approach to this is to implement this by newtyping around appropriate "off-the-shelf" monad transformers from the transformers library, but I found that this incurs a significant performance penalty.

I've tried to put some fairly extensive benchmarks in place, which you can find at https://github.com/ocharles/monad-yield. In that repository is a README.md file that describes how I have been performing these benchmarks. The benchmarks are defined over a common interface that each implementation of MonadYield exports. The benchmarks are defined in "Benchmarks.hs", and the three implementations are "Transformers.hs" (using transformers from GHC), "TransformersInline.hs" (using transformers-ocharles from that repository, which has many more INLINE pragmas) and "Inline.hs" (which doesn't depend on anything other than base).

There are three main benchmarks that are ran - one is benchmarking essentially the cost of ReaderT, the next the cost of StateT, and the last a composition of ReaderT over StateT over ReaderT. The results of the benchmark can be found here: https://ocharles.github.io/monad-yield/.

It seems that the current darcs release of transformers loses every time, but if I sprinkle {-# INLINE #-} across the definition of lazy state, I get identical performance to just writing out the lazy state monad by hand.

I was very surprised to see that I have to pay when I use transformers, and it seems like this cost can be removed at the cost of slightly larger interface files.

Before I submit a patch, I'd love to hear others thoughts. Should {-# INLINE #-} be necessary? Is there any reason not to add it to every symbol in transformers?

-- ocharles

Ross Paterson

unread,
Feb 16, 2016, 6:11:52 AM2/16/16
to haskel...@haskell.org
On Sun, Jan 24, 2016 at 06:21:38PM +0000, Oliver Charles wrote:
> I've tried to put some fairly extensive benchmarks in place, which you can find
> at https://github.com/ocharles/monad-yield. In that repository is a README.md
> file that describes how I have been performing these benchmarks. The benchmarks
> are defined over a common interface that each implementation of MonadYield
> exports. The benchmarks are defined in "Benchmarks.hs", and the three
> implementations are "Transformers.hs" (using transformers from GHC),
> "TransformersInline.hs" (using transformers-ocharles from that repository,
> which has many more INLINE pragmas) and "Inline.hs" (which doesn't depend on
> anything other than base).
>
> There are three main benchmarks that are ran - one is benchmarking essentially
> the cost of ReaderT, the next the cost of StateT, and the last a composition of
> ReaderT over StateT over ReaderT. The results of the benchmark can be found
> here: https://ocharles.github.io/monad-yield/.
>
> It seems that the current darcs release of transformers loses every time, but
> if I sprinkle {-# INLINE #-} across the definition of lazy state, I get
> identical performance to just writing out the lazy state monad by hand.
>
> I was very surprised to see that I have to pay when I use transformers, and it
> seems like this cost can be removed at the cost of slightly larger interface
> files.
>
> Before I submit a patch, I'd love to hear others thoughts. Should {-# INLINE #
> -} be necessary? Is there any reason not to add it to every symbol in
> transformers?

Thanks for this analysis. I've now added INLINE to just about everything,
per your suggestion.
_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

David Sorokin

unread,
Feb 16, 2016, 7:24:34 AM2/16/16
to Ross Paterson, haskel...@haskell.org
Ross,

In the past I noticed a very similar thing, but only I prefer using the INLINABLE pragma with monad transformers, for the INLINE pragma may lead to the performance degradation in some cases.

Thanks,
David

> 16 февр. 2016 г., в 14:11, Ross Paterson <R.Pat...@city.ac.uk> написал(а):

Reply all
Reply to author
Forward
0 new messages