Lazy computation being repeated?
Tyson Whitehead
twhitehead at gmail.com
Wed May 27 19:07:53 EDT 2009
I have a program that seems to me to be exhibiting strange behaviour.
Basically, it looks like something somewhere is not being updated, and this is
resulting in (very expensive) computation being repeated.
The program in question goes like so. The results from the expensive
calculation are stored in this structure
data Cache = Cache { cacheBits0 :: UArr Float,
cacheBits1 :: UArr Float }
and computed by this function (which takes several gigs of RAM)
cacheIndex :: ... -> Cache
cacheIndex ... = ...
The main program is
main = catch prog error
where prog = do ...
let !cache = cacheIndex ...
...
run cache ...
...
The run function reads an input line from stdin and calls effectChange to
performs the indicated calculation
run cache ... = loop
where loop = do ...
case effectChange ... cache of
...
...
loop
The effectChange function is calculates the change in an auto correlation. It
is made much cheaper (order too fast to notice) through the use of a the one
time computations stored in cacheBits0 and cacheBits1 (order several seconds).
Whether cacheBits1 is used or not depends on the input, while cacheBits0 is
always used because I used lengthU cacheBits0 [the fast one from UArr] to get
the length of both of them. The first line of input causes a several second
delay and lots of memory to be allocated (the cacheBits are being computed).
Repeated lines of input respond very quickly and the memory stays mostly
constant, unless cacheBits1 is used, in which case there is always a delay of
several seconds and big jumps in memory allocation.
The only thing I can think of that each time effectsChange is being run and it
is uses cacheBits1, it causes it value to be recomputed. Indeed, the delay
and big memory jumps go away if I change all references of cacheBits1 to
cacheBits0 in effectsChange or make the data fields strict like so
data Cache = Cache { cacheBits0 :: !(UArr Float),
cacheBits1 :: !(UArr Float) }
Does this make sense? Am I missing some reason why this should be the
expected behaviour for this program?
Thanks! -Tyson
More information about the Glasgow-haskell-users
mailing list