Sie können erhebliche Einsparungen erzielen, indem Sie vermeiden, Ihre gesamte Eingabedatei als list
in den Speicher zu schlürfen von Linien.
Insbesondere sind diese Zeilen für die Speichernutzung schrecklich, da sie eine Spitzenspeichernutzung von bytes
beinhalten Objekt die Größe Ihrer gesamten Datei, plus eine list
Zeilen mit dem kompletten Inhalt der Datei:
file_content = obj['Body'].read().decode('utf-8').splitlines(True)
for line in file_content:
Für eine 1 GB große ASCII-Textdatei mit 5 Millionen Zeilen auf 64-Bit-Python 3.3+ ist das ein Spitzenspeicherbedarf von ungefähr 2,3 GB für nur die bytes
Objekt, die list
, und die einzelnen str
s in der list
. Ein Programm, das 2,3-mal so viel RAM benötigt wie die Größe der Dateien, die es verarbeitet, wird nicht auf große Dateien skaliert.
Um das Problem zu beheben, ändern Sie diesen ursprünglichen Code in:
file_content = io.TextIOWrapper(obj['Body'], encoding='utf-8')
for line in file_content:
Angesichts dessen obj['Body']
scheint für Lazy Streaming verwendbar zu sein
dies sollte beide entfernen Kopien der vollständigen Dateidaten aus dem Speicher. Verwenden von TextIOWrapper
bedeutet obj['Body']
wird träge gelesen und in Blöcken (mit jeweils wenigen KB) decodiert, und die Zeilen werden ebenfalls träge iteriert; dies reduziert den Speicherbedarf auf eine kleine, weitgehend festgelegte Menge (die Spitzenspeicherkosten würden von der Länge der längsten Zeile abhängen), unabhängig von der Dateigröße.
Aktualisierung:
Es sieht aus wie StreamingBody
implementiert nicht die io.BufferedIOBase
ABC. Es hat seine eigene dokumentierte API
aber das kann für einen ähnlichen Zweck verwendet werden. Wenn Sie den TextIOWrapper
nicht erstellen können die Arbeit für Sie erledigen (es ist viel effizienter und einfacher, wenn es zum Laufen gebracht werden kann), wäre eine Alternative:
file_content = (line.decode('utf-8') for line in obj['Body'].iter_lines())
for line in file_content:
Im Gegensatz zur Verwendung von TextIOWrapper
, es profitiert nicht von der Massendekodierung von Blöcken (jede Zeile wird einzeln dekodiert), aber ansonsten sollte es immer noch die gleichen Vorteile in Bezug auf die reduzierte Speichernutzung erzielen.