前幾天我發佈了這個問題:Haskell performance using dynamic programming,並建議使用ByteStrings而不是Strings。在使用ByteStrings實現算法後,程序崩潰,超出內存限制。動態Haskell中的空間泄漏
import Control.Monad
import Data.Array.IArray
import qualified Data.ByteString as B
main = do
n <- readLn
pairs <- replicateM n $ do
s1 <- B.getLine
s2 <- B.getLine
return (s1,s2)
mapM_ (print . editDistance) pairs
editDistance :: (B.ByteString, B.ByteString) -> Int
editDistance (s1, s2) = dynamic editDistance' (B.length s1, B.length s2)
where
editDistance' table (i,j)
| min i j == 0 = max i j
| otherwise = min' (table!((i-1),j) + 1) (table!(i,(j-1)) + 1) (table!((i-1),(j-1)) + cost)
where
cost = if B.index s1 (i-1) == B.index s2 (j-1) then 0 else 1
min' a b = min (min a b)
dynamic :: (Array (Int,Int) Int -> (Int,Int) -> Int) -> (Int,Int) -> Int
dynamic compute (xBnd, yBnd) = table!(xBnd,yBnd)
where
table = newTable $ map (\coord -> (coord, compute table coord)) [(x,y) | x<-[0..xBnd], y<-[0..yBnd]]
newTable xs = array ((0,0),fst (last xs)) xs
內存消耗似乎與n
成比例。輸入字符串的長度爲1000個字符。我希望Haskell在每個解決方案打印後釋放所有在editDistance
中使用的內存。這不是這種情況嗎?如果沒有,我該如何強制這個?
我看到的唯一的其他實際計算是cost
,但強制與seq
什麼也沒做。
我無法重現您的問題。你使用什麼版本的GHC?你在編譯什麼標誌? –
@ ThomasM.DuBuisson這是通過HackerRank比賽完成的。環境使用ghc 7.8,只提供512 MB的內存。據我所知,沒有標誌。 –
或者我誤解了你的問題。由於您在執行任何操作之前正在從stdin讀取「n」行字符串,所以肯定內存與'n'顯然是線性關係。是所有還是你正在觀察editDistance在某個維度上佔用太多內存? –