我有一個簡單的問題:給定一個整數列表,讀第一行爲N
。然後,讀取下N行並返回它們的總和。重複,直到N
= 0提高分塊列表的性能
我的第一種方法是用這樣的:
main = interact $ unlines . f . (map read) . lines
f::[Int] -> [String]
f (n:ls)
| n == 0 = []
| otherwise = [show rr] ++ (f rest)
where (xs, rest) = splitAt n ls
rr = sum xs
f _ = []
但它相對較慢。我已經用它
ghc -O2 --make test.hs -prof -auto-all -caf-all -fforce-recomp -rtsopts
time ./test +RTS -hc -p -i0.001 < input.in
凡input.in
是一個測試輸入,其中第一行是10萬,其次是100K的隨機數,其次是0。我們可以在下面,它的使用澳圖看異型(N)內存:
EDITED:我原來的問題是比較2點相同慢的方法。我已經更新了它與下面
最佳進場現在比較,如果我做的和反覆,而不是調用sum
,我得到的內存
{-# LANGUAGE BangPatterns #-}
main = interact $ unlines . g . (map read) . lines
g::[Int] -> [String]
g (n:ls)
| n == 0 = []
| otherwise = g' n ls 0
g _ = []
g' n (l:ls) !cnt
| n == 0 = [show cnt] ++ (g (l:ls))
| otherwise = g' (n-1) ls (cnt + l)
我恆量試圖理解第一個例子中導致性能損失的原因。我會猜想所有可能會被懶惰評估的東西?
未經測試的猜測:或許您在第一個示例中對'read'的兩次調用不使用相同的類型,例如有一些「整數」與「整數」問題。 (編輯:這個評論是關於問題的以前的版本) – 2014-09-21 21:15:01