Die Verwendung von cPickle zum Serialisieren eines großen Wörterbuchs verursacht MemoryError

8

Ich schreibe einen invertierten Index für eine Suchmaschine für eine Sammlung von Dokumenten. Momentan speichere ich den Index als Wörterbuch von Wörterbüchern. Das heißt, jedes Schlüsselwort wird einem Wörterbuch von docIDs- & gt; Positionen des Auftretens zugeordnet.

Das Datenmodell sieht ungefähr so ​​aus: {word: {doc_name: [location_list]}}

Das Erstellen des Indexes im Speicher funktioniert gut, aber wenn ich versuche, auf die Festplatte zu serialisieren, erhalte ich einen MemoryError. Hier ist mein Code:

%Vor%

Kurz vor der Serialisierung verwendet mein Programm etwa 50% Speicher (1,6 GB). Sobald ich cPickle anrufe, steigt meine Speicherbelegung auf 80% vor dem Absturz.

Warum verwendet cPickle so viel Speicher für die Serialisierung? Gibt es einen besseren Weg, dieses Problem anzugehen?

    
Stephen Poletto 18.02.2011, 03:52
quelle

3 Antworten

10

cPickle muss eine Menge zusätzlichen Speicher verwenden, da es die Zykluserkennung durchführt. Sie könnten versuchen, das Marshallemodul zu verwenden, wenn Sie sicher sind, dass Ihre Daten keine Zyklen haben

    
John La Rooy 18.02.2011, 04:38
quelle
0

Es gibt die andere Essiggurken-Bibliothek, die Sie ausprobieren könnten. Vielleicht gibt es auch einige cPickle-Einstellungen, die Sie ändern könnten.

Andere Optionen: Brechen Sie Ihr Wörterbuch in kleinere Stücke und cPickle jedes Stück. Dann setze sie wieder zusammen, wenn du alles einlegst.

Tut mir leid, das ist vage, ich schreibe nur von oben. Ich dachte mir, es könnte immer noch hilfreich sein, da niemand anders geantwortet hat.

    
Greg 18.02.2011 04:37
quelle
0

Sie verwenden möglicherweise das falsche Werkzeug für diesen Job. Wenn Sie eine große Menge an indizierten Daten beibehalten möchten, empfehlen wir dringend, eine SQLite-Datenbank auf der Festplatte (oder natürlich nur eine normale Datenbank) mit einem ORM wie SQLObject oder SQL Alchemy .

Diese werden sich um die banalen Dinge wie Kompatibilität kümmern, das Format für den Zweck optimieren und nicht alle Daten gleichzeitig im Speicher halten, so dass Ihnen der Speicher ausgeht ...

Hinzugefügt: Da ich sowieso an einem fast identischen Projekt gearbeitet habe, aber hauptsächlich, weil ich so ein netter Mensch bin, ist hier eine Demo, die scheinbar das tut, was Sie brauchen (es wird ein SQLite-Datei in Ihrem aktuellen Verzeichnis, und löschen Sie es, wenn eine Datei mit diesem Namen bereits existiert, also legen Sie es irgendwo leer):

%Vor%

Dies ist sicherlich nicht der einzige Weg (oder notwendigerweise der beste Weg), dies zu tun. Ob die Dokument- oder Word-Tabellen aus der Location-Tabelle separate Tabellen sein sollten, hängt von Ihren Daten und Ihrer typischen Verwendung ab. In Ihrem Fall könnte die "Word" -Tabelle wahrscheinlich eine separate Tabelle mit einigen zusätzlichen Einstellungen für Indexierung und Eindeutigkeit sein.

    
detly 18.02.2011 05:54
quelle