<div dir="ltr">Hello,<div><br></div><div>I was looking at cleaning up my refactoring a core loop of template rendering to go from a loop with many parameters</div><div><br></div><div><div>loop :: RenderConfig -> BlockMap -> InputBucket m -> Builder -> [Pieces] -> ExceptT StrapError m Builder</div>

</div><div><br></div><div>to a looped state monad transformer</div><div><br></div><div>loop :: [Pieces] -> RenderT m Builder</div><div><br></div><div><div>newtype RenderT m a = RenderT </div><div>  { runRenderT :: ExceptT StrapError (StateT (RenderState m) m) a </div>
<div>  } deriving ( Functor, Applicative, Monad, MonadIO )</div>
</div><div><br></div><div><div>data RenderState m = RenderState</div><div>  { position     :: SourcePos</div><div>  , renderConfig :: RenderConfig</div><div>  , blocks       :: BlockMap</div><div>  , bucket       :: InputBucket m</div>
<div>  }</div></div><div><br></div><div>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)</div>
<div><br></div><div>You can find some of the processing code here:</div><div><br></div><div><a href="https://github.com/hansonkd/StrappedTemplates/blob/321a88168d54943fc217553c873f188797c0d4f5/src/Text/Strapped/Render.hs#L189">https://github.com/hansonkd/StrappedTemplates/blob/321a88168d54943fc217553c873f188797c0d4f5/src/Text/Strapped/Render.hs#L189</a><br>
</div><div><br></div><div>With my old loop commented out.</div><div><br></div><div>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.</div>
<div><br></div><div>After profiling I see in the StateT, the report has a lot more CAFs and garbage collecting.</div><div><br></div><div>Here is the profiling report from my original version w/o StateT</div><div><a href="http://lpaste.net/108995">http://lpaste.net/108995</a><br>
</div><div><br></div><div>Slow version with StateT</div><div><a href="http://lpaste.net/108997">http://lpaste.net/108997</a><br></div><div><br></div><div>Here is the "makeBucket" function that is referenced (it is the same in both state and nonstate):</div>
<div><br></div><div><a href="https://github.com/hansonkd/StrappedTemplates/blob/321a88168d54943fc217553c873f188797c0d4f5/examples/big_example.hs#L24">https://github.com/hansonkd/StrappedTemplates/blob/321a88168d54943fc217553c873f188797c0d4f5/examples/big_example.hs#L24</a><br>
</div><div><br></div><div>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.</div>
<div><br></div><div><a href="http://imgur.com/a/2jOIf">http://imgur.com/a/2jOIf</a></div><div><br></div><div>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.</div>
<div><br></div><div>--</div><div>Kyle Hanson</div></div>