[Haskell-beginners] getting memory usage to be constant when mixing wav files

Renick Bell renick at gmail.com
Sun Feb 14 05:22:52 EST 2010

I've written a program that mixes wav files read in by hsndfile, and
it does so with reasonably satisfactory performance using RTS options
-A and -K. Unfortunately, it does not have constant memory usage.
Profiling the program shows that almost all of the memory allocation
comes down to the following two functions: the first which calculates
and writes the values of individual indexes to the target array
(longer), and the second which runs the first for all the indexes in
the shorter array.

addInBase :: IOCArray Int Double -> IOCArray Int Double -> (Int, Int) -> IO ()
addInBase longer shorter (!li,!si) = do
    x <- readArray longer li
    y <- readArray shorter si
    let result =  x + y
    writeArray longer li result

addIn :: IOCArray Int Double -> IOCArray Int Double -> Int -> Int ->
Int -> IO ()
addIn longer shorter shorterBounds !li !si
    | si >  shorterBounds = return ()
    | si <= shorterBounds = addInBase longer shorter (li,si)
            >> addIn longer shorter shorterBounds (li+1) (si+1)

Basically, the addIn function is called by mapM_ across a list of all
of the occurrences of the input wav files.

I've tried ! and seq in many different places and combinations, but I
cannot get the memory usage constant. How can I achieve that? What
technique or principle will show me more specifically what is not
being evaluated so that I can avoid this trouble in the future? I have
read the wiki pages on Strictness, Laziness, and Performance, but
maybe I have not fully understood how to apply what is written there
to this code.

Any help is greatly appreciated.

If you notice any other glaring mistakes or bad ideas in the code
above, I'm interested in that as well.

Renick Bell

More information about the Beginners mailing list