我正在尝试处理一个非常大的 unicode 文本文件(6GB+)。我想要的是计算每个唯一单词的频率。当我遍历文件时,我使用严格Data.Map
来跟踪每个单词的计数。该过程需要太多时间和太多内存(20GB+)。我怀疑地图很大,但我不确定它应该达到文件大小的 5 倍!代码如下所示。请注意,我尝试了以下方法:
使用
Data.HashMap.Strict
而不是Data.Map.Strict
.Data.Map
似乎在较慢的内存消耗增长率方面表现更好。ByteString
使用惰性而不是惰性读取文件Text
。然后我将其编码为 Text 进行一些处理,然后将其编码回ByteString
forIO
。import Data.Text.Lazy (Text(..), cons, pack, append) import qualified Data.Text.Lazy as T import qualified Data.Text.Lazy.IO as TI import Data.Map.Strict hiding (foldr, map, foldl') import System.Environment import System.IO import Data.Word dictionate :: [Text] -> Map Text Word16 dictionate = fromListWith (+) . (`zip` [1,1..]) main = do [file,out] <- getArgs h <- openFile file ReadMode hO <- openFile out WriteMode mapM_ (flip hSetEncoding utf8) [h,hO] txt <- TI.hGetContents h TI.hPutStr hO . T.unlines . map (uncurry ((. cons '\t' . pack . show) . append)) . toList . dictionate . T.words $ txt hFlush hO mapM_ hClose [h,hO] print "success"
我的方法有什么问题?就时间和内存性能而言,完成我想做的事情的最佳方法是什么?