
John Meacham wrote:
On Fri, Oct 20, 2006 at 10:38:39AM +0100, Simon Marlow wrote:
I'm not sure that -funbox-strict-fields always improves performance, even if you only do it on Ints for example. If you end up pulling out those fields and passing the Int to a lazy function, the Int will be re-boxed each time, leading to more allocation. This is the reason that -funbox-strict-fields isn't on by defualt, and why I recommend using {-# UNPACK #-} pragmas.
the happy medium I found in jhc was to always unbox any fields whose representation was smaller or equal to a pointer. It seems to work well.
The Clean compiler does it also (including Doubles), and it seems to work well. Re-boxing small/basic types introduces a small penalty, but specializing polymorphic functions for basic types usually helps. Lazy and higher-order function applications are (relatively) slow anyway.
another worthwhile optimization that benefits from this is unboxing all enums.
so data Bool = False | True
desugars into
data Bool = Bool# Int#
False = Bool# 0# True = Bool# 1#
this gives a lot of things the CPR quality that is so good for optimization and means they can be unboxed in data constructors.
a small problem is that the compiler now doesn't know that Int#'s pulled out of a Bool# can only take on the values 0# or 1#, which is useful for things like case alternative elimination. I am not sure how to best handle it, but right now I am thinking of supporting 'restricted unboxed integers' somehow...
John
The (unboxed) Bool type in Clean is also implemented as an (unboxed) Int, other enums are not unboxed however. I found that using only the values 0 and 1 for booleans, as Clean does, can be a pain when wrapping foreign C calls, since C uses any non-zero value for True. Arjen