非常に大きなユニコードテキストファイル(6GB +)を処理しようとしています。私が望むのは、それぞれのユニークな単語の頻度を数えることです。私は厳密なData.Map
を使用して、ファイルを横断するごとに各単語の数を記録します。 処理に時間がかかり過ぎ、メモリー(20GB以上)が多すぎます。私はマップが巨大だと思うが、私はそれがファイルのサイズの5倍に達するはずがわからない! コードを以下に示します。非常に大きなテキストファイルをレイジーテキストとバイトストリングで処理する
Data.HashMap.Strict
の代わりData.Map.Strict
を使用して:私は次のことを試してみましたのでご注意ください。Data.Map
は、メモリ消費の増加速度が遅いという点でより優れているようです。lazy
Text
の代わりにlazyByteString
を使用してファイルを読み込みます。そして、それをテキストにエンコードして何らかの処理を行い、次にのByteString
にエンコードします。私のアプローチと間違って何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"
?時間とメモリのパフォーマンスに関して私がしようとしていることを達成する最良の方法は何ですか?
ファイルには、おおよそ何個の異なる単語がありますか?そのような高いメモリ消費が避けられないかどうかに関するヒントを与えるはずです。 – leftaroundabout
ファイル全体をメモリに読み込んで処理していますか?そうであれば、メモリ使用量が多いことがわかります。ファイルを1行ずつ読み込みます。 – acfrancis
@acfrancis: 'Data.Text.Lazy.IO.hGetContents'は、その点を正しく理解するはずです。 – leftaroundabout