Space explosion

Simon Marlow simonmar@microsoft.com
Mon, 6 Jan 2003 15:14:40 -0000


>  > -- Specs contains the options for the simulation;=20
> rollBounds simply=20
> finds the lowest and highest possible rolls
>  > -- type RollValue =3D Int
>  > -- type RollValueDist =3D Array RollValue Int
>  > probDist :: Specs -> [RollValue] -> RollValueDist
>  > probDist specs rolls =3D
>  >    accumArray (+) 0 (rollBounds specs) [(r, 1) | r <- rolls]
>=20
> It should be doing an in-place array update as it evaluates the=20
> comprehension, but apparently something's being kept in memory longer=20
> than it has an excuse for.=20

It does do a sequence of in-place updates, but this is another instance
of the foldl space leak.  The additions aren't being performed strictly,
so the array is filling up with suspensions.

For example:

	accumArray (+) 0 (1,10) [(3,1), (3,1), (3,1), ...]

would produce this sequence of arrays as accumArray processed its input
list:

	{ (3,1), ... }
	{ (3,1+1), ... }
	{ (3,1+1+1), ... }

we should really have a strict version of accumArray (the lazy version
*is* useful sometimes: you can refer recursively to the final array, for
example).

A quick workaround in your case (GHC only, I'm afraid) is to use UArray
instead, available from Data.Array.Unboxed.  These arrays contain
unboxed values and are therefore strict by definition; and you can use
all the usual array operations including accumArray.  This workaround
only applies if you're using one of the types supported by UArray though
(Int, Char, and other base types).

Cheers,
	Simon