
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 http://the3rd2nd.com