ご挨拶、
次のプログラムでファイル全体がメモリにロードされている理由を理解しようとしていますが、「(***)」の下の行をコメントアウトすると、プログラムは一定の(約1.5M)スペースで実行されます。
編集:ファイルは約660MBで、列26のフィールドは「2009-10-01」のような日付文字列であり、100万行あります。このプロセスは、「getLine」に到達するまでに約810MBを使用します。
'split'を使用した文字列の分割に関連していると思いますか?ファイルから読み取られた基になるByteStringは、まだ参照されているため、ガベージコレクションできませんか?しかし、もしそうなら、私はBS.copyがそれを回避するだろうと思いました。計算を強制する方法についてのアイデア-効果を発揮するために「seq」を適切な場所に配置できないようです。
(注:ソースファイルはタブ区切りの行です)
前もって感謝します、
ケビン
module Main where
import System.IO
import qualified Data.ByteString.Lazy.Char8 as BS
import Control.Monad
type Record = BS.ByteString
importRecords :: String -> IO [Record]
importRecords filename = do
liftM (map importRecord.BS.lines) (BS.readFile filename)
importRecord :: BS.ByteString -> Record
importRecord txt = r
where
r = getField 26
getField f = BS.copy $ ((BS.split '\t' txt) !! f)
loopInput :: [Record] -> IO ()
loopInput jrs = do
putStrLn $ "Done" ++ (show $ last jrs)
hFlush stdout
x <- getLine
return ()
-- (***)
loopInput jrs
main = do
jrs <- importRecords "c:\\downloads\\lcg1m.txt"
loopInput jrs
