January 25, 2013
Writing Fast Haskell Laziness is both blessing and curse minimum = head. sort is O(n) for carefully-defined sort Memory usage seq, $! and bang patterns
Memoization Any thunk is only ever evaluted once Store thunks in a map indexed by the argument! Example: memofibs Data.MemoTrie and Data.MemoCombinators
Weak head normal form Strict: if f undefined = undefined
Weak head normal form Strict: if f undefined = undefined weak head normal form
Weak head normal form Strict: if f undefined = undefined weak head normal form For constructors, is different from undefined; e.g. [1,2,undefined], Just "whnf"
Weak head normal form Strict: if f undefined = undefined weak head normal form For constructors, is different from undefined; e.g. [1,2,undefined], Just "whnf" For functions, is not fully applied: const 2 3 is fully applied, const 2 is not
Weak head normal form Strict: if f undefined = undefined weak head normal form For constructors, is different from undefined; e.g. [1,2,undefined], Just "whnf" For functions, is not fully applied: const 2 3 is fully applied, const 2 is not Lambda expressions are always in WHNF
Weak head normal form Strict: if f undefined = undefined weak head normal form For constructors, is different from undefined; e.g. [1,2,undefined], Just "whnf" For functions, is not fully applied: const 2 3 is fully applied, const 2 is not Lambda expressions are always in WHNF Just undefined seq 2, [1..] seq 2 both evaluate to 2 and perform no extra forcing
Weak head normal form Strict: if f undefined = undefined weak head normal form For constructors, is different from undefined; e.g. [1,2,undefined], Just "whnf" For functions, is not fully applied: const 2 3 is fully applied, const 2 is not Lambda expressions are always in WHNF Just undefined seq 2, [1..] seq 2 both evaluate to 2 and perform no extra forcing What about 10 ^ 100 ^ 4 seq 2?
Weak head normal form Strict: if f undefined = undefined weak head normal form For constructors, is different from undefined; e.g. [1,2,undefined], Just "whnf" For functions, is not fully applied: const 2 3 is fully applied, const 2 is not Lambda expressions are always in WHNF Just undefined seq 2, [1..] seq 2 both evaluate to 2 and perform no extra forcing What about 10 ^ 100 ^ 4 seq 2? Both instances of (^) are fully applied, so haskell will compute 10 1004.
Styling and Profiling First: compile your programs like ghc --make -rtsopts -prof program.hs program +RTS -s will output basic profiling information to stderr program +RTS -p will output time profiling information to program.prof program +RTS -i0.001 -hc
Seq-ing strictnes How to use seq properly: let shared = expensive x in shared seq f shared
Seq-ing strictnes How to use seq properly: let shared = expensive x in shared seq f shared shared is reduced to WHNF
Seq-ing strictnes How to use seq properly: let shared = expensive x in shared seq f shared shared is reduced to WHNF How not to use seq: expensive x seq f (expensive x)
Other speedups Bang-patterns: let!x = 2 + 3 in x + 6 forces x Compiling with -O2 Don t just throw seq everywhere!
Testing with Hspec Unit tests Autogenerated tests using QuickCheck!
Other libraries lens for first-class data access netwire for functional reactive programming OpenGL bindings