[Haskell-cafe] Performance of StateT and best practices for debugging

Kyle Hanson me at khanson.io
Thu Aug 7 17:57:47 UTC 2014


I was looking at cleaning up my refactoring a core loop of template
rendering to go from a loop with many parameters

loop :: RenderConfig -> BlockMap -> InputBucket m -> Builder -> [Pieces] ->
ExceptT StrapError m Builder

to a looped state monad transformer

loop :: [Pieces] -> RenderT m Builder

newtype RenderT m a = RenderT
  { runRenderT :: ExceptT StrapError (StateT (RenderState m) m) a
  } deriving ( Functor, Applicative, Monad, MonadIO )

data RenderState m = RenderState
  { position     :: SourcePos
  , renderConfig :: RenderConfig
  , blocks       :: BlockMap
  , bucket       :: InputBucket m

however, there is a big slow down (about 6-10x) using a StateT. I think it
might have something to do with laziness but I am not exactly sure of where
to begin in tracking it down. Swapping out the Lazy State to a Strict State
helps a little (only a 5x slow down)

You can find some of the processing code here:


With my old loop commented out.

Its messy right now since I am just trying a number of different
approaches. I did some more work factoring out the lifts, trying different
iterations of foldlM and stuff but that didn't have that much of an effect
on performance.

After profiling I see in the StateT, the report has a lot more CAFs and
garbage collecting.

Here is the profiling report from my original version w/o StateT

Slow version with StateT

Here is the "makeBucket" function that is referenced (it is the same in
both state and nonstate):


Looking at stacked overflow and the official docs I have gotten an idea of
what is going on. The heaps generated between them tells me that a lot more
memory is being allocated to lists. These heaps were generated running my
render function against a template with nested loops and a list of elements.


I am hoping that maybe someone could give me a hint at what to look at
next. I've played around with Strictness and refactoring loops to no avail
and now am kind of stuck. Any help would be appreciated.

Kyle Hanson
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20140807/a82b99f5/attachment.html>

More information about the Haskell-Cafe mailing list