U kunt aanzienlijke besparingen behalen door te voorkomen dat u uw hele invoerbestand in het geheugen slurpt als een list
lijnen.
In het bijzonder zijn deze regels verschrikkelijk wat betreft geheugengebruik, in die zin dat ze een piekgeheugengebruik van bytes
met zich meebrengen object de grootte van uw hele bestand, plus een list
van regels met ook de volledige inhoud van het bestand:
file_content = obj['Body'].read().decode('utf-8').splitlines(True)
for line in file_content:
Voor een ASCII-tekstbestand van 1 GB met 5 miljoen regels, op 64 bit Python 3.3+, is dat een piekgeheugenvereiste van ongeveer 2,3 GB voor slechts de bytes
object, de list
, en de individuele str
s in de list
. Een programma dat 2,3x zoveel RAM nodig heeft als de grootte van de bestanden die het verwerkt, schaalt niet naar grote bestanden.
Om dit op te lossen, wijzigt u die originele code in:
file_content = io.TextIOWrapper(obj['Body'], encoding='utf-8')
for line in file_content:
Gezien het feit dat obj['Body']
lijkt bruikbaar voor luie streaming
dit zou beide moeten verwijderen kopieën van de volledige bestandsgegevens uit het geheugen. TextIOWrapper
gebruiken betekent obj['Body']
wordt lui gelezen en gedecodeerd in brokken (van een paar KB per keer), en de regels worden ook lui herhaald; dit vermindert de geheugenbehoefte tot een kleine, grotendeels vaste hoeveelheid (de piekgeheugenkosten zijn afhankelijk van de lengte van de langste regel), ongeacht de bestandsgrootte.
Bijwerken:
Het lijkt op StreamingBody
implementeert de io.BufferedIOBase
. niet ABC. Het heeft wel zijn eigen gedocumenteerde API
dat kan echter voor een soortgelijk doel worden gebruikt. Als u de TextIOWrapper
. niet kunt maken het werk voor u doen (het is veel efficiënter en eenvoudiger als het kan worden gemaakt), een alternatief zou zijn om te doen:
file_content = (line.decode('utf-8') for line in obj['Body'].iter_lines())
for line in file_content:
In tegenstelling tot het gebruik van TextIOWrapper
, profiteert het niet van bulkdecodering van blokken (elke regel wordt afzonderlijk gedecodeerd), maar verder zou het nog steeds dezelfde voordelen moeten behalen in termen van verminderd geheugengebruik.