Nachdem ich das letzte bisschen Leistung aus einigen Haskell herausgequetscht habe, die ich verwende, um Tweet-Daten in N-Gramme zu brechen, stoße ich auf ein Problem mit dem Platzleck. Wenn ich profile, verwendet der GC etwa 60-70% des Prozesses und es gibt signifikante Speicherbereiche, die zum Ziehen bestimmt sind. Hoffentlich kann ein Haskell-Guru vorschlagen, wenn ich falsch liege.
%Vor% Eine kleine Optimierung besteht darin, die Daten zu filtern (mit HashMap.filter
), bevor Sie sie sortieren. Dies hat mir geholfen, 2 Sekunden von der letzten Ausführungszeit abzuziehen. Eine andere Sache, die ich gemacht habe, war die Verwendung von Sequenzen ( Data.Sequence
) anstelle von Listen (kein merklicher Unterschied :-(). Meine Version kann gefunden werden hier .
Wenn ich auf das Heap-Profil schaue, glaube ich nicht, dass es in Ihrem Programm ein Leck im Raum gibt:
Sie erstellen gerade eine ziemlich große Hash-Tabelle (377141 Schlüssel / Wert-Paare) im Speicher und verwerfen sie dann nach einer gewissen Verarbeitung. Laut Johans Beitrag nimmt eine Hashtabelle dieser Größe an ca. 5 * N + 4 * (N-1) Wörter = 3394265 * 4 Bytes ~ = 13 MiB, was mit dem übereinstimmt, was das Heap-Profil zeigt. Der verbleibende Platz wird durch die Schlüssel und Werte belegt. Auf meinem Computer ist die Zeit in GC etwa 40%, was nicht unvernünftig klingt, da Sie ständig die Hash-Tabelle und die temporären "Stacks" aktualisieren, während Sie mit den Daten keine Berechnungen durchführen. Da die einzige Operation, für die Sie die Hash-Tabelle benötigen, insertWith
ist, ist es vielleicht besser, eine veränderbare Datenstruktur zu verwenden?
Update : Ich habe Ihr Programm mit einer veränderbaren Hash-Tabelle umgeschrieben. Interessant ist die Geschwindigkeit Der Unterschied ist nicht groß, aber der Speicherverbrauch ist etwas besser:
Wie Sie sehen, bleibt die Größe des Blocks, der für die Hash-Tabelle reserviert ist, während der gesamten Ausführung konstant.
Tags und Links haskell memory-leaks space