Ich versuche eine sehr große Unicode-Textdatei (6GB +) zu verarbeiten. Ich möchte die Häufigkeit jedes einzelnen Wortes zählen. Ich verwende eine strikte Data.Map
, um die Zählungen jedes Wortes zu verfolgen, während ich die Datei durchquere. Der Prozess dauert zu viel Zeit und zu viel Speicher (20 GB +). Ich vermute, dass die Map riesig ist, aber ich bin mir nicht sicher, dass sie die 5-fache Größe der Datei erreichen sollte! Der Code ist unten gezeigt. Bitte beachten Sie, dass ich versuchte, die folgenden:Verarbeitung einer sehr großen Textdatei mit faulen Texten und ByteStrings
Mit
Data.HashMap.Strict
stattData.Map.Strict
.Data.Map
scheint im Hinblick auf eine langsamere Erhöhung des Speicherverbrauchs besser zu funktionieren.Lesen der Dateien mit Lazy
ByteString
statt LazyText
. Und dann kodiere ich es zu Text, mache etwas Verarbeitung und kodiere es dann wieder zurück zuByteString
fürIO
.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"
Was mit meinem Ansatz falsch? Was ist der beste Weg, um das zu erreichen, was ich in Bezug auf Zeit und Speicherleistung versuche?
Wie viele verschiedene Wörter gibt es ungefähr in der Datei? Das sollte einen Hinweis geben, ob solch ein hoher Speicherverbrauch unvermeidlich ist. – leftaroundabout
Liest du die ganze Datei in den Speicher, um sie zu verarbeiten? Wenn ja, erklärt sich der hohe Speicherverbrauch. Versuchen Sie, Zeile für Zeile in der Datei zu lesen. – acfrancis
@acfrancis: 'Data.Text.Lazy.IO.hGetContents' sollte diesen Punkt sicherlich richtig machen. – leftaroundabout