<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Apr 29, 2014 at 9:31 AM, Niklas Hambüchen <span dir="ltr"><<a href="mailto:mail@nh2.me" target="_blank">mail@nh2.me</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This is just a short notice that using<br>
<br>
   foldl' (+) 0 [0..100000::Int]<br>
<br>
is over 10 times slower than using<br>
<br>
  flip execState 0 $<br>
    forLoop (0 :: Int) (< n) (+1) $ \i -> do<br>
      x <- get<br>
      put $! x + i<br>
<br>
with `loopFor` as on <a href="https://github.com/nh2/loop" target="_blank">https://github.com/nh2/loop</a>.<br></blockquote><div><br></div><div>So this is interesting.  The forLoop code gets compiled into a nice loop in core over unboxed Ints.  The foldl' function OTOH still goes via a list.  I expect it's not foldl' itself that's slow, rather that it doesn't fuse with the list producers in current GHCs.  This may be improved in the future.  Especially as the vectorized foldl' does fuse.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Even using an IORef is twice as fast as the pure foldl' (but still 5<br>
times slower than strict State).<br>
<br>
The benchmark is at<br>
<a href="http://htmlpreview.github.io/?https://github.com/nh2/loop/blob/master/results/bench-foldl-and-iorefs-are-slow.html" target="_blank">http://htmlpreview.github.io/?https://github.com/nh2/loop/blob/master/results/bench-foldl-and-iorefs-are-slow.html</a>.<br>

<br>
(All benchmarks are linked from <a href="https://github.com/nh2/loop" target="_blank">https://github.com/nh2/loop</a>.)<br>
<br>
You can see there that the problem is gone when using Vector.foldl', but<br>
only for Int - for Word32 it persists.<br>
<br>
It seems that manual looping is beneficial even when dealing with prime<br>
examples of pure code that GHC ought to optimize well.<br></blockquote><div><br></div><div>That's why I suggested using vector in the first place.  But it seems that Vector.enumFromTo could use some optimizations to help with some common cases.</div>
<div><br></div><div>John</div></div></div></div>