2010-07-22 2 views
10

Ich war Python-Skripte ausführen, die mehrere Anrufe auf einige Funktionen machen, sagen F1 (x) und F2 (x), die ein bisschen wie folgt aussehen:Statischer Speicher in Python: Erstellen Schleifen neue Instanzen von Variablen im Speicher?

x = LoadData() 

for j in range(N): 
    y = F1(x[j]) 
    z[j] = F2(y) 

    del y 

SaveData(z) 

Leistung ist viel schneller, wenn ich halten die "del y" -Linie. Aber ich verstehe nicht, warum das so ist. Wenn ich nicht "del y" benutze, dann habe ich schnell keinen RAM mehr und muss auf virtuellen Speicher zurückgreifen, und alles wird langsam zum Crawlen. Buy, wenn ich "del y" verwende, dann spüle ich wiederholt und ordne den Speicher für y neu. Was ich gerne tun würde, ist, dass Sie als statischer Speicher sitzen und den Speicher bei jedem F1 (x) -Aufruf wiederverwenden. Aber von dem, was ich sagen kann, passiert das nicht.

Auch nicht sicher, ob es relevant ist, aber meine Daten bestehen aus numpy Arrays.

+0

Diese Frage geht wahrscheinlich davon aus, dass y zuerst innerhalb der Schleife deklariert wird, ich hätte dies erwähnen sollen. Fühlen Sie sich frei, diesen Aspekt der Frage zu kommentieren! –

+3

Wenn Sie das explizite 'del y' nicht mögen, dann extrahieren Sie den Schleifenkörper in eine Funktion. Auf diese Weise werden alle Variablen innerhalb der Schleife automatisch für jede Iteration bereinigt. – Duncan

Antwort

11

Ohne die del y benötigen Sie möglicherweise doppelt so viel Speicher. Dies liegt daran, dass y für jeden Durchlauf durch die Schleife an den vorherigen Wert F1 gebunden ist, während der nächste berechnet wird.

Sobald F1 zurückgibt, wird y auf diesen neuen Wert zurückprallen und das alte F1 Ergebnis kann freigegeben werden.

Dies würde bedeuten, dass das Objekt zurück von F1 viel Speicher ganz besetzt

die Schleife für den ersten paar Iterationen Abrollen wie diese

y = F1(x[0]) # F1(x[0]) is calculated, then y is bound to it 
z[j] = F2(y) 
y = F1(x[1]) # y is still bound to F1(x[0]) while F1(x[1]) is computed 
       # The memory for F1(X[0]) is finally freed when y is rebound 
z[j] = F2(y) 

del y ist, wenn eine gute Lösung mit aussehen würde Das ist in Ihrem Fall passiert.

+0

hören hören - das erklärt völlig, warum Sie eine bessere Leistung mit 'del y' haben –

+1

Danke, das muss genau sein, was passiert: Ohne die del verdoppelt sich mein Speicherverbrauch ein wenig in virtuellen Speicher (da mein RAM passiert liegen zwischen ein und zwei Instanzen von y) und das Skript slappt bei niedriger Leistung auf. Ich werde für jetzt mit der Del-Lösung bleiben; Nochmals vielen Dank für die Erklärung, wann/wie die Instanzen von y erstellt werden. –

0

Verwenden Sie für sehr große Werte von Nxrange anstelle von range zum Speichern von Speicher. Sie können auch Funktionen verschachteln, aber ich weiß nicht, ob Ihnen das hilft. : \

x = LoadData() 

for j in xrange(N): 
    z[j] = F2(F1(x[j])) 

SaveData(z) 

Vielleicht unnötige Kopien von Objekten F1 und F2 machen, wäre die beste Art und Weise an Ort und Stelle sein, wie etwas:

x = LoadData() 
for item in x: 
    item.F1() 
    item.F2() 
SaveData(x) 

Leider antworten, wenn möglicherweise nicht hilfreich

+0

Ich machte mir Sorgen, dass mein Beispiel eine Verschachtelung erlauben würde; Es ist nicht so praktisch eine Option im eigentlichen Skript.Ich denke, gnibbler's Feedback beschreibt die Situation richtig, aber danke für dein Feedback. Ich war mit der XRange-Funktion erst vertraut, als Sie darauf hingewiesen haben. –

1

Was Sie eigentlich wollen, ist etwas, das in Python seltsam ist - Sie wollen eine Region von Speicher für y zuweisen und den Zeiger auf diese Region an F1() übergeben, damit es diese Region verwenden kann, um den nächsten Wert von zu erstellen y. dies zu vermeiden, die F1() tun es für den neuen Wert von y eigenen Zuteilungs ist, auf die Referenz, die dann in Ihre eigene Variable geschrieben y (die berechnet eigentlich nicht der Wert dessen, was F1() ist, sondern ein Verweis darauf)

Es gibt bereits eine SO-Frage über die Weitergabe durch Verweis in Python: How do I pass a variable by reference?

Verwandte Themen