> "Simon Marlow" <[EMAIL PROTECTED]> writes:
>
> > You can save storage by using strict constructor fields and using
> > the -funbox-strict-fields flag. eg.
>
> This would be switched on automatically with -O, no?
Actually no... but perhaps it's time to turn it on. The reason it's not on by default
is that there are cases where it can make performance *worse* - storing the value
unboxed occasionally requires us to reconstruct the boxed version eg. for passing to a
polymorphic function or storing in an ordinary list.
> > data FloatList = FloatNil | FloatCons !Float FloatList
>
> ..while without strictness, the compiler wouldn't be able to unbox it,
> and then we'd have three words per cons, *plus* two words per Float,
> right?
Yes, spot on.
> > requires 3 words for each float in the list, because its actual
> > representation is
>
> > data FloatList = FloatNil | FloatCons Float# FloatList
>
> I'm going to sketch my data structure, and try to reason a bit about
> it. Let's see
>
> I have an (Array Int Foo), where Foo is a set of nullary constructors
> (in other words, cheap?). I have a list of Bar = Bar (Array Int Foo)
> Int (where the array is the same for all elements), and construct a
> list of tuples (Int, Bar).
>
> So the array shouldn't be too costly, I think - but perhaps an UArray
> would reduce cost from three words to one word per element?
It already costs one word per element (think of nullary constructors as free - we only
have one copy of each nullary constructor which everybody points to).
If the array is the same for each element, why store it in the list at all?
> The list of Bars should require three words per cons cell, and three
> words for each Bar, and then two words for the Ints (which could be
> saved by an exclamation mark).
Yes.
> The list of tuples should again cost three words per cons, three per
> tuple, plus two words per Int (with the Bars already existing and only
> moved around).
>
> Summing up, the array is 3n, the first list is (3+3+2)n = 7n, and the
> second list is (3+3+2)n = 7n, for a grand total of 17n, or multiplied
> with four to get the bytes, 68n bytes.
>
> This isn't too far from what I observe, so I hope my analysis is
> somewhat correct. :-)
Yes, sounds right.
> ---
>
> Now for improvement upon it: I'll try to use an UArray, and see if
> that reduces the array size somewhat.
I don't think it'll make a difference.
> For the list of Bar's, I can strictify the Ints to save 2 words. But
> if I defined
>
> data BarList = Bar (Array Int Foo) !Int (BarList) |BarNil,
>
> I should be able to get away with 4 words per Bar, shouldn't I
> (disregarding the actual array, which is shared anyway)?
>
> And for the tuple-list, I could do
>
> data TupleList = Tuple !Int Bar TupleList | TupleNil
>
> and get 4n, which is equally good.
>
> ---
>
> This is assuming the compiler doesn't do any of this on its own...
The compiler won't do any of this on its own. Remember that you can't pass a BarList
to standard list functions like length, for example, because the types (and
representations) are different. The compiler won't make data constructor fieds strict
- except in simple cases it would need a sophisticated whole-program analysis to
ensure that adding the annotation wouldn't change the behaviour of the program, and
AFAIK no-one has attempted this.
Cheers,
Simon
_______________________________________________
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users