Warum erhöht das Laden zwischengespeicherter Objekte den Speicherverbrauch drastisch, wenn sie nicht berechnet werden?

8

Relevante Hintergrundinformationen

Ich habe eine kleine Software entwickelt, die über eine Konfigurationsdatei angepasst werden kann. Die Konfigurationsdatei wird analysiert und in eine verschachtelte Umgebungsstruktur übersetzt (zB .HIVE $ db = eine Umgebung, .HIVE $ db $ user="Horst", .HIVE $ db $ pw="mein Passwort", .HIVE $ regex $ Datum = einige Regex für Daten etc.)

Ich habe Routinen entwickelt, die mit diesen verschachtelten Umgebungen umgehen können (z. B. den Wert "db / user" oder "regex / date" nachschlagen, ändern usw.). Die Sache ist, dass das anfängliche Parsen der Konfigurationsdateien sehr lange dauert und zu einem ziemlich großen Objekt führt (eigentlich drei bis vier, zwischen 4 und 16 MB). Also dachte ich "Kein Problem, lassen Sie uns sie einfach zwischenspeichern, indem Sie die Objekte in .Rdata-Dateien speichern". Das funktioniert, aber das "Laden" zwischengespeicherter Objekte führt dazu, dass mein Rterm-Prozess in Bezug auf den RAM-Verbrauch (über 1 GB !!) durch das Dach geht und ich verstehe immer noch nicht wirklich warum (das nicht passieren, wenn ich das Objekt neu "compute", aber genau das versuche ich zu vermeiden, da es zu lange dauert.

Ich habe bereits darüber nachgedacht, es vielleicht zu serialisieren, aber ich habe es nicht getestet, da ich meinen Code ein wenig umgestalten müsste. Außerdem bin ich mir nicht sicher, ob es den "Zurückladen in R" -Teil genauso beeinflussen würde wie das Laden von .RData-Dateien.

Frage

Kann mir jemand sagen, warum das Laden eines zuvor berechneten Objekts solche Auswirkungen auf den Speicherverbrauch meines Rterm-Prozesses hat (verglichen mit der Berechnung in jedem neuen Prozess, den ich beginne) und wie kann man das am besten vermeiden?

Falls gewünscht, werde ich auch versuchen, ein Beispiel zu finden, aber es ist ein bisschen schwierig, mein genaues Szenario zu reproduzieren. Aber ich werde es versuchen.

    
Rappster 31.10.2011, 16:26
quelle

2 Antworten

8

Es ist wahrscheinlich, weil die Umgebungen, die Sie erstellen, ihre Vorfahren mit sich herumtragen. Wenn Sie die Vorfahreninformationen nicht benötigen, setzen Sie die Eltern solcher Umgebungen auf emptyenv() (oder verwenden Sie keine Umgebungen, wenn Sie sie nicht benötigen).

Beachten Sie auch, dass Formeln (und natürlich Funktionen) Umgebungen haben, also achten Sie auch auf diese.

    
G. Grothendieck 31.10.2011, 17:25
quelle
3

Wenn es von anderen nicht reproduziert werden kann, wird es schwer zu beantworten sein. Ich mache jedoch etwas ähnliches wie Sie, aber ich benutze JSON-Dateien, um alle meine Werte zu speichern. Anstatt den Text zu parsen, verwende ich RJSONIO, um alles in eine Liste zu konvertieren, und Dinge aus einer Liste zu bekommen, ist sehr einfach. (Sie könnten, wenn Sie möchten, in einen Hash konvertieren, aber es ist schön, Ebenen verschachtelter Parameter zu haben.)

Siehe diese Antwort für ein Beispiel von wie ich das gemacht habe. Wenn das für Sie klappt, können Sie auf den teuren Übersetzungsschritt und die Ballooning-Funktion verzichten.

(Ein Stich auf die ursprüngliche Frage ...) Ich frage mich, ob Ihr Problem ist, dass Sie eine Umgebung und nicht eine Liste verwenden. Das Sichern von Umgebungen kann in einigen Kontexten schwierig sein. Listen speichern ist kein Problem. Versuchen Sie es mit einer Liste oder versuchen Sie, in / aus einer Umgebung zu konvertieren. Sie können dazu die Funktionen as.list() und as.environment() verwenden.

    
Iterator 31.10.2011 17:19
quelle

Tags und Links