- Don't use -O or (especially) -O2:
By using them, you are telling GHC that you are willing to suffer
longer compilation times for better-quality code.
GHC is surprisingly zippy for normal compilations without -O!
- Use more memory:
Within reason, more memory for heap space means less garbage
collection for GHC, which means less compilation time. If you use the
-Rghc-timing option, you'll get a garbage-collector
report. (Again, you can use the cheap-and-nasty +RTS -Sstderr
-RTS option to send the GC stats straight to standard error.)
If it says you're using more than 20% of total time in garbage
collecting, then more memory would help.
If the heap size is approaching the maximum (64M by default), and you
have lots of memory, try increasing the maximum with the
-M<size> option, e.g.: ghc -c -O
-M1024m Foo.hs.
Increasing the default allocation area size used by the compiler's RTS
might also help: use the -A<size>
option.
If GHC persists in being a bad memory citizen, please report it as a
bug.
- Don't use too much memory!
As soon as GHC plus its “fellow citizens” (other processes on your
machine) start using more than the real memory on your
machine, and the machine starts “thrashing,” the party is
over. Compile times will be worse than terrible! Use something
like the csh-builtin time command to get a report on how many page
faults you're getting.
If you don't know what virtual memory, thrashing, and page faults are,
or you don't know the memory configuration of your machine,
don't try to be clever about memory use: you'll just make
your life a misery (and for other people, too, probably).
- Try to use local disks when linking:
Because Haskell objects and libraries tend to be large, it can take
many real seconds to slurp the bits to/from a remote filesystem.
It would be quite sensible to compile on a fast machine using
remotely-mounted disks; then link on a slow machine that had
your disks directly mounted.
- Don't derive/use Read unnecessarily:
It's ugly and slow.
- GHC compiles some program constructs slowly:
Deeply-nested list comprehensions seem to be one such; in the past,
very large constant tables were bad, too.
We'd rather you reported such behaviour as a bug, so that we can try
to correct it.
The part of the compiler that is occasionally prone to wandering off
for a long time is the strictness analyser. You can turn this off
individually with -fno-strictness.
To figure out which part of the compiler is badly behaved, the
-v2 option is your friend.
If your module has big wads of constant data, GHC may produce a huge
basic block that will cause the native-code generator's register
allocator to founder. Bring on -fvia-C
(not that GCC will be that quick about it, either).
- Explicit import declarations:
Instead of saying import Foo, say import
Foo (...stuff I want...) You can get GHC to tell you the
minimal set of required imports by using the
-ddump-minimal-imports option (see Section 4.9.4).
Truthfully, the reduction on compilation time will be very small.
However, judicious use of import declarations can make a
program easier to understand, so it may be a good idea anyway.