È possibile ottenere un risparmio significativo evitando di riporre in memoria l'intero file di input come un list
di righe.
In particolare, queste righe sono terribili sull'utilizzo della memoria, in quanto implicano un picco di utilizzo della memoria di un bytes
obiettare la dimensione dell'intero file, più un list
di righe anche con il contenuto completo del file:
file_content = obj['Body'].read().decode('utf-8').splitlines(True)
for line in file_content:
Per un file di testo ASCII da 1 GB con 5 milioni di righe, su Python 3.3+ a 64 bit, è un requisito di memoria di picco di circa 2,3 GB per solo i bytes
oggetto, l'list
e il singolo str
s nell'list
. Un programma che necessita di 2,3 volte la quantità di RAM rispetto alle dimensioni dei file che elabora non verrà ridimensionato a file di grandi dimensioni.
Per correggere, cambia il codice originale in:
file_content = io.TextIOWrapper(obj['Body'], encoding='utf-8')
for line in file_content:
Dato che obj['Body']
sembra essere utilizzabile per lo streaming lento
questo dovrebbe rimuovere entrambi copie dei dati del file completo dalla memoria. Utilizzo di TextIOWrapper
significa obj['Body']
viene letto e decodificato pigramente in blocchi (di pochi KB alla volta) e anche le righe vengono ripetute pigramente; questo riduce le richieste di memoria a una quantità piccola, in gran parte fissa (il costo di picco della memoria dipenderebbe dalla lunghezza della linea più lunga), indipendentemente dalle dimensioni del file.
Aggiornamento:
Sembra StreamingBody
non implementa io.BufferedIOBase
ABC. Ha una propria API documentata
tuttavia, che può essere utilizzato per uno scopo simile. Se non riesci a creare il TextIOWrapper
fa il lavoro per te (è molto più efficiente e semplice se può essere fatto funzionare), un'alternativa sarebbe fare:
file_content = (line.decode('utf-8') for line in obj['Body'].iter_lines())
for line in file_content:
Diversamente dall'utilizzo di TextIOWrapper
, non beneficia della decodifica in blocco dei blocchi (ogni riga viene decodificata individualmente), ma in caso contrario dovrebbe comunque ottenere gli stessi vantaggi in termini di utilizzo ridotto della memoria.