Glasgow Haskell comes with a time and space profiling system. Its purpose is to help you improve your understanding of your program's execution behaviour, so you can improve it.
Any comments, suggestions and/or improvements you have are welcome. Recommended “profiling tricks” would be especially cool!
The GHC approach to profiling is very simple: annotate the expressions you consider “interesting” with cost centre labels (strings); so, for example, you might have:
f x y = let output1 = _scc_ "Pass1" ( pass1 x ) output2 = _scc_ "Pass2" ( pass2 output1 y ) output3 = _scc_ "Pass3" ( pass3 (output2 `zip` [1 .. ]) ) in concat output3
The costs of the evaluating the expressions bound to output1, output2 and output3 will be attributed to the “cost centres” Pass1, Pass2 and Pass3, respectively.
The costs of evaluating other expressions, e.g., concat output4, will be inherited by the scope which referenced the function f.
You can put in cost-centres via _scc_ constructs by hand, as in the example above. Perfectly cool. That's probably what you would do if your program divided into obvious “passes” or “phases”, or whatever.
If your program is large or you have no clue what might be gobbling all the time, you can get GHC to mark all functions with _scc_ constructs, automagically. Add an -auto compilation flag to the usual -prof option.
Once you start homing in on the Guilty Suspects, you may well switch from automagically-inserted cost-centres to a few well-chosen ones of your own.
To use profiling, you must compile and run with special options. (We usually forget the “run” magic!—Do as we say, not as we do…) Details follow.
If you're serious about this profiling game, you should probably read one or more of the Sansom/Peyton Jones papers about the GHC profiling system. Just visit the Glasgow FP group web page…