Go to the first, previous, next, last section, table of contents.
- 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 `-Rgc-stats' option, you'll get a garbage-collector report.
(Again, you can use the cheap-and-nasty `-optCrts-Sstderr' 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.
You ask for more heap with the `-H<size>'
option; e.g.: `ghc -c -O -H16m Foo.hs'.
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 an NFS filesystem (say).
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 `read' for `Text' unnecessarily:
- When doing `deriving Text',
use `-fomit-derived-read'
to derive only the `showsPrec' method. Quicker, smaller code.
- Don't re-export instance declarations:
- (Note: This recommendation totally violates the Haskell language
standard.)
The Haskell module system dictates that instance declarations are
exported and re-exported into interface files with considerable gusto.
In a large system, especially one with mutually-recursive modules,
this tendency makes your interface files bigger (bad) and decreases
the chances that changes will be propagated incorrectly (bad).
If you wish, you may use a language-violating option,
`-fomit-reexported-instances',
to get just the effect you might expect. It can't help but
speed things up.
- 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 parts of the compiler that seem most prone to wandering off for a
long time are the abstract interpreters (strictness and update
analysers). You can turn these off individually with
`-fno-strictness' and
`-fno-update-analysis'.
If `-ddump-simpl' produces output after a reasonable time, but
`-ddump-stg' doesn't, then it's probably the update analyser
slowing you down.
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.
If `-ddump-absC' produces output after a reasonable time, but
nothing after that -- it's probably the native-code generator. Bring
on `-fvia-C' (not that GCC will be that quick about it, either).
- Avoid the consistency-check on linking:
- Use `-no-link-chk'; saves effort. This is probably
safe in a I-only-compile-things-one-way setup.
- Explicit `import' declarations:
- Instead of saying `import Foo', say
`import Foo (...stuff I want...)'.
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.
Go to the first, previous, next, last section, table of contents.