Um den Overhead der Datenstruktur in Ihrem Code zu testen, schrieb ich das folgende Testprogramm. Es nimmt an, dass Ihre Textdatei N
Megabyte in ASCII-Codierung mit relativ kurzen Zeilen war. (Ich hatte N
450-150 zu ändern, nachdem meine physischen Speicher liefen.)
import sys
MB = 1024 * 1024
line = "the quick brown fox jumps over the lazy dog"
megs = 150
nlines = (megs * MB)/len(line)
d = {}
for i in xrange(nlines):
d[i] = line.split(' ')
dict_size = sys.getsizeof(d)
list_size = sum(sys.getsizeof(a) for a in d.items())
item_size = sum(sum(sys.getsizeof(s) for s in a) for a in d.items())
print " dict:", dict_size/float(MB), "MB"
print "lists:", list_size/float(MB), "MB"
print "items:", item_size/float(MB), "MB"
print "total:", (dict_size + list_size + item_size)/float(MB), "MB"
mit dem Ergebnis:
dict: 192.00 MB
lists: 251.16 MB
items: 669.77 MB
total: 1112.9 MB
den Activity Monitor beobachten, überschreitet der Python-Prozess 2 Gigabyte Speichernutzung , also gibt es auch etwas Speicher, der nicht berücksichtigt wurde. Artefakte der malloc
Implementierung könnten eine Möglichkeit sein.
ich das gleiche Programm in C++ implementiert:
#include <string>
#include <vector>
#include <unordered_map>
int main()
{
int const MB = 1024 * 1024;
std::string const line = "the quick brown fox jumps over the lazy dog";
std::vector<std::string> const split = {
"the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"
};
int const megs = 150;
int const nlines = (megs * MB)/line.size();
std::unordered_map<int, std::vector<std::string>> d;
for (int i = 0; i < nlines; ++i) {
d[i] = split;
}
}
mit clang++ -O3
Zusammengestellt, benutzten über 1 GB Arbeitsspeicher. C++ hat nicht sys.getsizeof()
, also erfordert es etwas mehr Arbeit, um die Speicherauslastung zu brechen, und ich habe diese Arbeit nicht getan.
Zweimal der Speicher des äquivalenten C++ ist eigentlich ein ziemlich gutes Ergebnis für Python, deshalb entferne ich meine Kommentare vor der Bearbeitung der cPython-Implementierung.
Ich denke, Ihr Hauptproblem besteht darin, die Zeile als ein Array von kurzen Strings zu speichern. Ist es möglich, die Zeilen als ganze Strings zu speichern und nach Bedarf aufzuteilen, aber nicht auf einmal?
Was ist das Endziel Ihres Programms?
Leider hat jede Zeile mindestens 100 Wörter zu 1000 Wörtern !! Wie kann ich meinen Code komplizieren? – Arman
Eigentlich, wenn ich mein Programm auf "line = 10 *" ändere, springt der schnelle braune Fuchs über den faulen Hund "', der Speicherverbrauch sinkt sehr, auch für die 'Items'. Das ist überraschend - ich würde nur erwarten, dass der 'dict'- und' list'-Overhead sinken würde. – japreiss
hinzugefügt einen C++ - Vergleich und neue Schlussfolgerungen, siehe Änderungen. – japreiss