[Haskell-cafe] mapM vs mapM_ performance
Luke Palmer
lrpalmer at gmail.com
Thu Apr 24 04:37:15 EDT 2008
On Tue, Apr 22, 2008 at 11:32 AM, Ben <midfield at gmail.com> wrote:
> Hello Haskellers,
>
> I'm running ghc 6.8.2 on vista 64. Consider the following program,
> which is compiled with -02 -prof -auto-all:
>
> module Main where
>
> import System.IO (openFile, IOMode(..), hPutStr)
>
> testlst = let ls = [(i, [(j, (fromIntegral j)::Float) | j <-
> [1..5]::[Int]]) | i <- [1..500000]::[Int]]
> in ls
>
> main2 = do
> h <- openFile "bardump" WriteMode
> mapM_ ((hPutStr h) . show) testlst
>
>
> main = do
> h <- openFile "bardump2" WriteMode
> mapM ((hPutStr h) . show) testlst
> return ()
>
> main and main2 are different in only that mapM_ versus mapM_ are used.
> But the mapM version runs about 20x slower! I'm running with +RTS -p
> -hc -RTS and I see that the amount of memory allocated is about the
> same, and I think the resident memory is about the same too. But the
> mapM_ version runs in about 8.7 seconds, and the mapM version takes
> 167 seconds.
My first guess is that the garbage collector is not running at all in
the mapM_ version, but is working it's ass off in the mapM version
cleaning up the list that will never be used.
> You may ask, why use mapM if you're discarding the values?
> Unfortunately in my real app I need the values, which are more
> interesting than IO ().
If you need the values, then you've got to pay that price I suppose.
If you need the values, I'm going to take a stab that in your real app
you use a lot of memory because of this (because presumably you're
keeping the values around), whereas you're just seeing a speed hit on
this small test program.
Luke
More information about the Haskell-Cafe
mailing list