<div dir="ltr">I recall having this issue also, and I eventually ending up concluding that GHC didn't optimise away the list in "mapM_". Try with GHC 7.10 though, it seems to be better with optimising lists into simple loops. </div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 3, 2015 at 6:18 PM, Baojun Wang <span dir="ltr"><<a href="mailto:wangbj@gmail.com" target="_blank">wangbj@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<div><br></div><div>First of all, I found it interesting that </div><div><br></div><div>loopM_ f k n s = when (k <= n) (f k >> loopM_ f (s+k) n s)</div><div><br></div><div>loopM_ seems faster than mapM_ ( mapM_ f [k, k+s..n]))</div><div><br></div><div>I think mapM_ is used very commonly, why it's performance is even lower than a hand-written loop function?</div><div><br></div><div>2nd, even I replace mapM_ with loopM_ from above, when chain IO action, it still can leak space. ( Because IO Monad (>>) need keep ``RealWorld s'' updated so that I/O actions can be done in-order? )</div><div><br></div><div>Consider below function:</div><div><br></div><div><div>f3 :: UArray Int Int -> IOUArray Int Int64 -> Int -> IO ()</div><div>f3 u r i = let !v = u ! i</div><div> in go (f31 v) i i</div><div> where f31 v j = readArray r j >>= \v1 -></div><div> writeArray r j (v1 + (fromIntegral i) * (fromIntegral v))</div><div> f31 :: Int -> Int -> IO ()</div><div> go g k s = when (k <= maxn) (</div><div> g k >> go g (s+k) s )</div></div><div><br></div><div>When call f3:</div><div> </div><div> loopM_ (f3 uu res) 1 1 1000000<br></div><div><br></div><div>Which will have blow profiling output:</div><div><br></div>individual inherited<br>COST CENTRE MODULE no. entries %time %alloc %time %alloc<br><br><br>...<br> loopM_ Main 104 4000002 7.4 10.1 100.0 99.3<br> f3 Main 113 1000000 1.0 2.0 70.2 69.1<br> f3.go Main 116 14970034 32.7 67.1 68.8 67.1 <br> f3.f31 Main 117 13970034 34.5 0.0 36.1 0.0<br> f3.f31.\ Main 118 13970034 1.7 0.0 1.7 0.0<br> f3.f31 Main 114 0 0.3 0.0 0.4 0.0<br> f3.f31.\ Main 115 0 0.1 0.0 0.1 0.0<br>...<div>Why f3.go consumes so much space (67.1%)? The only reason I can think of is IO Monad chain (>>) isn't space free as I thought.</div><div><br></div><div>Did I get something fundamentally wrong?</div><div><br></div><div>Thanks</div><span class="HOEnZb"><font color="#888888"><div>baojun</div></font></span></div>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br></div>