Python-Effizienz und große Objekte im Speicher

8

Ich habe mehrere Prozesse, die jeweils mit Listen arbeiten, die 40000 Tupel enthalten. Dies maximiert den auf der Maschine verfügbaren Speicher nahezu. wenn ich das tue:

%Vor%

befreit dies mehr Speicher?

    
tipu 05.04.2013, 02:50
quelle

2 Antworten

7

Da collection mit der gleichen Rate schrumpft wie rows , wird Ihre Speicherauslastung stabil bleiben. Der Aufruf gc.collect() macht keinen großen Unterschied.

Das Speichermanagement in CPython ist subtil. Nur weil Sie Referenzen entfernen und einen Erfassungszyklus ausführen, bedeutet dies nicht unbedingt, dass der Speicher an das Betriebssystem zurückgegeben wird. Siehe diese Antwort für Details .

Um wirklich Speicher zu sparen, sollten Sie diesen Code um Generatoren und Iteratoren statt um große Listen von Elementen strukturieren. Ich bin sehr überrascht, dass Sie sagen, dass Sie Verbindungstimeouts haben, weil das Abrufen aller Zeilen nicht viel mehr Zeit in Anspruch nehmen sollte als das gleichzeitige Abrufen einer Zeile und das Durchführen der einfachen Verarbeitung, die Sie ausführen. Vielleicht sollten wir uns Ihren DB-Abruf-Code ansehen?

Wenn eine row-at-time-Verarbeitung wirklich nicht möglich ist, dann bewahren Sie Ihre Daten zumindest als unveränderliche Deque auf und führen Sie die gesamte Verarbeitung mit Generatoren und Iteratoren durch.

Ich werde diese verschiedenen Ansätze skizzieren.

Zuerst einige allgemeine Funktionen:

%Vor%

Nun ist das Ideal eine reihenweise Verarbeitung wie folgt:

%Vor%

Dies nimmt die kleinstmögliche Speichermenge - nur eine Zeile nach der anderen.

Wenn Sie wirklich die gesamte Ergebnismenge speichern müssen, können Sie den Code leicht ändern:

%Vor%

Nun sammeln wir alle Ergebnisse in collection first, die für den gesamten Programmlauf vollständig im Speicher bleiben.

Wir können jedoch auch Ihren Ansatz des Löschens von Sammlungselementen bei ihrer Verwendung duplizieren. Wir können dieselbe "Code-Form" beibehalten, indem wir einen Generator erstellen, der seine Quellensammlung so leert, wie sie funktioniert . Es würde ungefähr so ​​aussehen:

%Vor%

Jetzt können Sie einfach drain(collection) für collection ersetzen, wenn Sie Speicherplatz freigeben möchten. Nachdem drain(collection) erschöpft ist, ist das collection -Objekt leer.

    
Francis Avila 05.04.2013, 05:31
quelle
2

Wenn Ihr Algorithmus von der linken Seite oder vom Anfang einer Liste abhängt, können Sie deque Objekt aus Sammlungen als schnellere Alternative.

Zum Vergleich:

%Vor%

Drucke:

%Vor%

Also ist für diesen speziellen Test des Herausspringens vom Anfang der Liste oder Warteschlange deque mehr als 10x schneller.

Dieser große Vorteil ist jedoch nur für die linke Seite. Wenn Sie denselben Test mit pop () ausführen, ist die Geschwindigkeit ungefähr gleich. Sie können die Liste auch an der richtigen Stelle umkehren und von der rechten Seite aufspringen, um dieselben Ergebnisse wie von der Deque zu erhalten.

Im Sinne von "Effizienz" wird es viel effizienter sein, einzelne Zeilen aus der Datenbank zu verarbeiten. Wenn das keine Option ist, bearbeiten Sie Ihre Liste (oder Deque) "Sammlung" an Ort und Stelle.

Versuchen Sie etwas in dieser Richtung.

Brechen Sie zuerst die Zeilenverarbeitung aus:

%Vor%

Sehen Sie sich nun eine Deque an, um schnelle Pops von links zu ermöglichen:

%Vor%

Oder wenn Sie bei einer Liste bleiben möchten:

%Vor%

Ich denke, dass Ihr ursprünglicher Ansatz von pop (0), die Zeile verarbeiten und gc alle 5000 Zeilen aufrufen, wahrscheinlich suboptimal ist. Das GC wird automatisch viel öfter automatisch aufgerufen.

Meine letzte Empfehlung:

  1. Verwenden Sie deque . Es ist wie ein list , aber schneller für Links-Push oder Pops;
  2. Verwenden Sie popleft() , sodass Sie die Liste nicht umkehren müssen (wenn die Reihenfolge von collection sinnvoll ist);
  3. Bearbeiten Sie Ihre Sammlung als Generator;
  4. Wirf die Vorstellung aus, gc aufzurufen, weil es nichts für dich tut.
  5. Werfen Sie hier 1-4 aus, wenn Sie einfach die db aufrufen und 1 Zeile bekommen und 1 Zeile gleichzeitig verarbeiten können!
dawg 05.04.2013 04:56
quelle