私は数日前にこの質問を投稿しました:Haskell performance using dynamic programmingで、StringsではなくByteStringsを使用することをお勧めしました。 ByteStringsでアルゴリズムを実装した後、プログラムがクラッシュし、メモリ制限を超えます。ダイナミックハスケルのスペースリーク
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のメモリしか与えません。私が知っている限り、フラグはありません。 –
または、おそらく私はあなたの問題を誤解します。確かに、メモリは明らかに 'n 'で線形です。これは、操作を実行する前にstdinから' n'行の文字列を読み込んでいるためです。それはすべてですか、それともeditDistanceがある次元で余りにも多くのメモリを取っているのを観察していますか? –