Saluti,Haskell stringhe di byte - per finire con file di grandi dimensioni caricati in memoria
Sto cercando di capire perché sto vedendo l'intero file caricato in memoria con il seguente programma, ma se si commento la riga sotto "(***)" quindi il programma viene eseguito in uno spazio costante (circa 1,5 M).
MODIFICA: il file è di circa 660 MB, il campo nella colonna 26 è una stringa di data come '2009-10-01' e ci sono un milione di righe. Il processo utilizza circa 810 MB nel momento in cui raggiunge il 'getLine'
Ho ragione nel ritenere che sia correlato alla divisione della stringa utilizzando 'split' e che in qualche modo il sottostante ByteString che è stato letto dal file possa essere raccolto dai rifiuti perché è ancora referenziato? Ma se è così, allora pensavo che BS.copy avrebbe funzionato su questo. Qualche idea su come forzare il calcolo - Non riesco a ottenere 'seq' nel posto giusto per avere un effetto.
(NB il file sorgente è linee separati da tabulazione)
Grazie in anticipo,
Kevin
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
Sarebbe utile avere il file o almeno alcune statistiche a riguardo. Non sono convinto che il tuo problema non sia il risultato di mantenere tutti i '[Record]' in memoria in una volta (forzato dalla chiamata 'putStrLn ... last jrs'). L'intero elenco deve rimanere in memoria perché lo passi in 'loopInput' - se hai passato solo' last jrs', o se hai consumato solo il capo dell'elenco prima di forzare il resto, allora potresti eseguire un'elaborazione incrementale dello spazio costante. EDIT: Inoltre, fare un po 'di profilazione dell'heap. –
Il file è di circa 660 MB, il campo nella colonna 26 è una stringa di data come '2009-10-01' e ci sono un milione di righe. Il processo utilizza circa 810 MB nel momento in cui raggiunge il "getLine". Saluti! – Kevin