Haskell 使用文本键控哈希表时内存泄漏

Haskell 使用文本键控哈希表时内存泄漏,haskell,memory-leaks,hashtable,Haskell,Memory Leaks,Hashtable,我正在使用HashTable包在Haskell中编写Bayes朴素分类器。然而,当处理更大的语料库时,我有大量的内存泄漏,这可能是由大量的值更新引起的。当加载已经指定的字数时,它需要大约2GB的RAM,但当从语料库中计算字数时,8GB的RAM是不够的,它只是崩溃了。我怎样才能预防它?计算单词的代码如下所示: chars :: T.Text chars = "qwertyuiopasdfghjklzxcvbnmęóąśłżźćń\t " el :: Char -> T.Text ->

我正在使用HashTable包在Haskell中编写Bayes朴素分类器。然而,当处理更大的语料库时,我有大量的内存泄漏,这可能是由大量的值更新引起的。当加载已经指定的字数时,它需要大约2GB的RAM,但当从语料库中计算字数时,8GB的RAM是不够的,它只是崩溃了。我怎样才能预防它?计算单词的代码如下所示:

chars :: T.Text
chars = "qwertyuiopasdfghjklzxcvbnmęóąśłżźćń\t "

el :: Char -> T.Text -> Bool
el = T.any . (==)

preprocess :: T.Text -> [T.Text]
preprocess !line = T.words . T.map check . T.toLower $ line
             where check !x = if x `el` chars then x else ' '

loop :: Handle -> Corpus -> IO ()
loop hdl dic =
    hIsEOF hdl >>= \x -> if x
        then return ()
        else do
          cl:dat <- preprocess <$> TIO.hGetLine hdl
          let ins !word =
                        if (T.length word <= 20) && (T.length word >= 4)
                          then (H.lookup dic word >>=
                                \mprob -> case mprob of
                                   Just (SexProbs m f) -> do
                                     H.delete dic word
                                     H.insert dic word $ if cl == "m" then SexProbs (m+1) f else SexProbs m (f+1)
                                   Nothing -> H.insert dic word $ if cl == "m" then SexProbs 1 0 else SexProbs 0 1)
                          else return ()
          mapM_ ins dat
          loop hdl dic

分析表明,最大的分配来源是预处理和循环,但我不知道如何减少内存使用。

原因似乎是您的SexProbs数据类型。它可能是用惰性字段定义的,即假定计数器为Int:

data SexProbs = SexProbs Int Int
用SexProbs m+1 n构造一个新值不会计算加法,而是在堆内存中放置一个thunk。这些积累会导致空间泄漏

为了避免这种情况,请使用seq强制计算计数器

或更改类型定义以使用严格字段:

data SexProbs = SexProbs !Int !Int

你能列出你的进口商品吗?您使用的哈希表变量是文本严格型还是惰性型?还要添加SexProbs的定义-除非字段严格,否则+1将导致泄漏。您是如何编译的?我使用的是来自哈希表包和严格文本的布谷鸟哈希表。我省略了SexProbs字段中的严格性注释。谢谢你的帮助。
data SexProbs = SexProbs !Int !Int