在大文件中计算字符时,内存不足



我想计算大文件中每个字符的出现数量。尽管我知道应该在Haskell中以严格的方式实施计数(我试图使用FoldL'实现计数),但我仍然没有记忆。为了进行比较:文件大小约为2GB,而计算机具有100GB的内存。该文件中没有很多不同的字符 - 也许20。我在做什么错?

ins :: [(Char,Int)] -> Char -> [(Char,Int)]
ins [] c = [(c,1)]
ins ((c,i):cs) d
    | c == d = (c,i+1):cs
    | otherwise = (c,i) : ins cs d
main = do
    [file] <- getArgs
    txt <- readFile file
    print $ foldl' ins [] txt

您的ins功能正在创建大量导致大量内存泄漏的thunk。foldl'仅评估弱头正常形式,此处还不够。您需要的是Control.DeepSeqdeepseq,以便到达正常形式

另外,使用Data.Map.Strict代替关联列表进行计数。另外,如果您的IO处于2GB的订单,则最好使用懒惰的ByteString代替普通字符串。

波纹管代码应在恒定内存空间中执行,而不管输入的大小如何:

import System.Environment (getArgs)
import Data.Map.Strict (empty, alter)
import qualified Data.ByteString.Lazy.Char8 as B
main :: IO ()
main = getArgs >>= B.readFile . head >>= print . B.foldl' go empty
  where
  go = flip $ alter inc
  inc :: Maybe Int -> Maybe Int
  inc Nothing  = Just 1
  inc (Just i) = Just $ i + 1

最新更新