readArray :: IOUArray i Int -> i -> IO Int で読んだ結果を即座に使っているにも関わらず、GHC.Prim.readIntArray# の結果の (# RealWorld, Int# #) をわざわざ一度 (# RealWorld, Int #) に変換するようにコンパイルされてしまって、heap allocation が発生して、うぎゃーとなっている。

昔から、IOモナドを使うと CPR analysis と worker/wrapper transformation を上手くやってくれない感じで、GHCのコンパイル結果には不満だったけど、未だに相変わらずなんだなぁ。

上記は GHC 6.12.1 での話なので、とりあえず GHC 7.0.4 入りの Haskell Platform 2011.4.0.0 に移行してみるかなぁ……
まあ、改善してるとはあまり期待はできないとは思うけれど。