forM_ [1..N] does not get fused (allocates 50% more)
Apparently idiomatic code like forM_ [1.._N]
does not get fused away.
This can give serious performance problems when unnoticed.
-- Slow:
forM_ [0.._N-1] $ \i -> do ...
-- Around 10 times faster:
loop _N $ \i -> do ...
{-# INLINE loop #-}
loop :: (Monad m) => Int -> (Int -> m ()) -> m ()
loop bex f = go 0
where
go !n | n == bex = return ()
| otherwise = f n >> go (n+1)
Full code example: https://gist.github.com/nh2/8905997 - the relevant alternatives are commented.
Edited by george.colpitts