> * I find it difficult to understand how the code I write translates
> into actual algorithms, memory management, etc.  Haskell is such a
> nice language that it hides all this detail from me :-).  So, I'd be
> grateful for a reference or two on this area.

Manuel pointed out Simon's paper on the STG machine, which is a good place
to start.  You can see the STG code before code generation for any given
module by adding the -ddump-stg option to GHC's command line (you can also
see Core, GHC's typed intermediate language, by using -ddump-simpl, but that
tends to include a lot of type information and can be harder to read).

> * I added a reasonable amount of added strictness in `obvious' kind of
> places, but with no visible effect on performance.  Does adding
> strictness help with CPU use as well as with memory use ?  Where is it
> most beneficial to add strictness ?

Strictness annotations on data constructor arguments are usually a good
idea.  With GHC, if you mark a constructor argument strict and it's a
single-constructor or flat datatype (eg. Int or a tuple), and you give the
flag '-funbox-strict-fields', then the argument will be unboxed.  This can
be a big win, but may be a slight loss in certain conditions.  We're looking
for evidence to support making -funbox-strict-fields the default.

> * Most of my program is in a state-threading monad of my own (built
> out of normal functional pieces).  The main program (which is in the
> IO monad) invokes the `grind handle on state machine' function,
> passing the action to perform and the initial state and getting the
> new state back.  Is this good, bad, or ugly ?  It does make it easy to
> decouple the nasty I/O handling event loop part of the program from
> the clean, supposedly predictable, state engine.  (Yes, the program
> does really need to be a state engine.)

If you don't need a lazy state monad, strict ones are usually faster.  eg.

        m >>= k = \s -> case m s of (a, s) -> k a s

is going to be faster than

        m >>= k = \s -> let (a, s') = m s in k a s'

If you can use the ST monad instead of your own monad, that will be faster
still, since the ST monad (and IO) has virtually zero overhead in GHC.

> * In particular, the bit of code that seems to be slow is the part
> responsible for updating a part of the state whose type is broadly
> speaking
> 
>    Array (x,y) [value]
> 
> I need to do similar cumulative updates to the values in a whole
> region of the array, and I do it with (basically) this
[snip]

Take a look at the new IArray and MArray modules in GHC's lang library.
They have some nice abstractions over flat mutable and immutable arrays, and
still support some of Haskell's nice Array combinators, such as accum.
You'll need to have an underlying ST or IO monad to use the mutable
versions, though.

Cheers,
        Simon

Reply via email to