Warum Essiggurke Speicher essen?
Ich versuche damit umzugehen, große Mengen von eingelegten Daten durch kleine Stücke auf die Festplatte zu schreiben. Hier ist der Beispielcode:
from cPickle import *
from gc import collect
PATH = r'd:\test.dat'
@profile
def func(item):
for e in item:
f = open(PATH, 'a', 0)
f.write(dumps(e))
f.flush()
f.close()
del f
collect()
if __name__ == '__main__':
k = [x for x in xrange(9999)]
func(k)
open () und close () werden innerhalb der Schleife platziert, um mögliche Ursachen für die Anhäufung von Daten im Speicher auszuschließen.
Zur Veranschaulichung des Problems füge ich die Ergebnisse der Speicherprofilerstellung bei, die mit dem Python 3d-Partymodul erstellt wurdenSpeicher_Profiler:
Line # Mem usage Increment Line Contents
==============================================
14 @profile
15 9.02 MB 0.00 MB def func(item):
16 9.02 MB 0.00 MB path= r'd:\test.dat'
17
18 10.88 MB 1.86 MB for e in item:
19 10.88 MB 0.00 MB f = open(path, 'a', 0)
20 10.88 MB 0.00 MB f.write(dumps(e))
21 10.88 MB 0.00 MB f.flush()
22 10.88 MB 0.00 MB f.close()
23 10.88 MB 0.00 MB del f
24 collect()
Während der Ausführung der Schleife tritt eine merkwürdige Speicherauslastung auf. Wie kann es beseitigt werden? Irgendwelche Gedanken?
Wenn die Menge der Eingabedaten zunimmt, kann das Volumen dieser zusätzlichen Daten sehr viel größer werden als das der Eingabe (upd: in der realen Aufgabe erhalte ich 300 + Mb)
Und eine weiter gefasste Frage: Welche Möglichkeiten gibt es, um mit großen Mengen an E / A-Daten in Python richtig zu arbeiten?
upd: Ich habe den Code so umgeschrieben, dass nur der Loop-Body übrig bleibt, um zu sehen, wann das Wachstum spezifisch stattfindet, und hier die Ergebnisse:
Line # Mem usage Increment Line Contents
==============================================
14 @profile
15 9.00 MB 0.00 MB def func(item):
16 9.00 MB 0.00 MB path= r'd:\test.dat'
17
18 #for e in item:
19 9.02 MB 0.02 MB f = open(path, 'a', 0)
20 9.23 MB 0.21 MB d = dumps(item)
21 9.23 MB 0.00 MB f.write(d)
22 9.23 MB 0.00 MB f.flush()
23 9.23 MB 0.00 MB f.close()
24 9.23 MB 0.00 MB del f
25 9.23 MB 0.00 MB collect()
Es scheint, als würde dumps () den Speicher auffressen. (Während ich eigentlich dachte, es wird schreiben ())