我想生成一个包含不同整数的树并找到它们的总和.这是代码:
{-# LANGUAGE BangPatterns #-}
import Control.Applicative
import Control.Monad.Trans.State
data Tree a = Leaf a | Branch (Tree a) a (Tree a)
new = get <* modify' (+ 1)
tree :: Integer -> Tree Integer
tree n = evalState (go n) 0 where
go 0 = Leaf <$> new
go n = Branch <$> go (n - 1) <*> new <*> go (n - 1)
sumTree = go 0 where
go !a (Leaf n) = a + n
go !a (Branch l n r) = go (go (a + n) l) r
main = print $sumTree (tree 20)
用-O2编译它会导致
348,785,728 bytes allocated in the heap
147,227,228 bytes copied during GC
34,656,860 bytes maximum residency (13 sample(s))
35,468 bytes maximum slop
72 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 565 colls, 0 par 0.764s 1.024s 0.0018s 0.0071s
Gen 1 13 colls, 0 par 0.936s 1.014s 0.0780s 0.3214s
INIT time 0.000s ( 0.001s elapsed)
MUT time 0.936s ( 0.764s elapsed)
GC time 1.700s ( 2.038s elapsed)
EXIT time 0.000s ( 0.002s elapsed)
Total time 2.636s ( 2.805s elapsed)
%GC time 64.5% (72.7% elapsed)
Alloc rate 372,631,936 bytes per MUT second
Productivity 35.5% of total user, 33.4% of total elapsed
为什么我会漏这个空间?如何删除它?
最佳答案 无论何时构建树,您都应该尝试从上到下独立工作.这通常适用于懒惰,并发,缓存利用率,GC效率等.您构建的树只是按顺序编号的完整二叉树.我建议你考虑使用以下签名并做一些转移:
tree :: Bits b => Int -> Tree b
你可以打破一个起点的辅助函数.