Haskell Profiling Guide — GHC Profiling, Cost Centers, and Optimization
In this tutorial, you will learn about Haskell Profiling Guide. We cover key concepts, practical examples, and best practices to help you master this topic.
Haskell profiling with GHC measures time and allocation per function using cost centers (-fprof-auto), heap profiling (-hy) for memory analysis, and thread scope (-l) for concurrency -- guiding optimizations like INLINE pragmas, strictness annotations, and worker-wrapper transformations.
Enabling Profiling
# Compile with profiling
ghc -prof -fprof-auto -rtsopts Main.hs
# Run with time and allocation profile
./Main +RTS -p
# View in Main.prof file
# Shows cost centers sorted by time and allocation
Profiling Output
COST CENTRE MODULE %time %alloc
processFile Main 45.2 52.1
parseLine Main 28.3 30.4
readInput Main 15.1 10.2
Heap Profiling
# Heap profile by closure type
./Main +RTS -hy -RTS
# By module
./Main +RTS -hm -RTS
# Generate graph
hp2ps -c Main.hp
# Produces Main.ps (postscript graph)
# Limit sample interval
./Main +RTS -i0.1 -hy -RTS
Optimization Pragmas
{-# LANGUAGE BangPatterns #-}
-- INLINE: force inlining
{-# INLINE process #-}
process :: Int -> Int
process x = x * 2 + 1
-- SPECIALIZE: monomorphize for specific types
{-# SPECIALIZE sumTree :: Tree Int -> Int #-}
-- NOINLINE: prevent inlining (for code size)
{-# NOINLINE expensiveFunction #-}
-- Strict fields
data Config = Config
{ timeout :: !Int
, retries :: !Int
}
Thread Scope
# Thread profile for concurrent programs
./Main +RTS -l -RTS
# Produces Main.eventlog
# View with threadscope
threadscope Main.eventlog
Common Mistakes
1. Profiling without optimization
Profile with -O2 for realistic results. Without optimization, profiling shows unoptimized code paths.
2. Ignoring allocation
Time spent on GC (shown as %GC in +RTS -s) indicates excessive allocation. Reduce allocations, not just operations.
3. Over-optimizing early
Profile first, optimize bottlenecks. GHC is already quite good at optimization. Focus on algorithmic improvements.
Practice Questions
1. How do you enable profiling?
Compile with -prof -fprof-auto -rtsopts and run with +RTS -p.
2. What does -hy show? Heap profile by closure type, showing which constructors/function closures use memory.
3. What does INLINE pragma do? Tells GHC to inline the function at every call site, eliminating call overhead at the cost of code size.
FAQ
{{< faq question="What is a cost center?" >}} Annotated code region with timing and allocation statistics. GHC automatically creates cost centers with -fprof-auto. {{< /faq >}}
{{< faq question="How do I reduce GC time?" >}} Reduce allocations: use strict fields, unboxed types, fusion (stream/loop). Monitor with +RTS -s. Target < 20% GC time. {{< /faq >}}
{{< faq question="What is the difference between -p and -h?" >}} -p produces a time/allocation profile. -h produces a heap profile (memory usage over time). {{< /faq >}}
What's Next
Now learn about documentation with Haddock.
| Topic | Description | Link |
|---|---|---|
| Documentation | Haddock documentation | {{< ref "24-documentation" >}} |
| Stack Build | Stack build tool | {{< ref "25-stack-build" >}} |
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro