HA

Haskell Performance

Haskell performance patterns for avoiding space leaks, forcing evaluation, and profiling with GHC tools

Details

Language / Topic
haskellHaskell
Category
Performance

Rules

balanced
- Use `Data.Text` and `Data.ByteString` instead of `String` for all I/O — `String` is a linked list of `Char` and has catastrophic performance at scale.
- Use `seq` or `deepseq` (via `NFData`) to force evaluation before storing values in accumulators — lazy accumulators build up thunks that cause heap blowup.
- Enable `{-# LANGUAGE BangPatterns #-}` and use `!` on strict accumulator arguments in recursive helpers to eliminate thunk allocation.
- Profile heap allocation with `+RTS -hc -p` and view the report with `hp2ps` — identify the closure type causing space leaks before optimising.
- Use `Data.Map.Strict` and `Data.HashMap.Strict` (from `unordered-containers`) instead of their lazy counterparts for maps used as mutable state.
- Use `Data.Vector` for dense numeric arrays — it provides cache-friendly storage and `SIMD`-friendly bulk operations via `vector-algorithms`.
- Use `ghc-options: -O2` in release builds and `-fno-full-laziness` to prevent GHC from floating bindings in ways that cause inadvertent retention.