Se pueden obtener ahorros significativos al evitar sorber todo el archivo de entrada en la memoria como una list
de líneas.
Específicamente, estas líneas son terribles en el uso de memoria, ya que implican un uso máximo de memoria de bytes
objeto el tamaño de todo el archivo, más una list
de líneas con el contenido completo del archivo también:
file_content = obj['Body'].read().decode('utf-8').splitlines(True)
for line in file_content:
Para un archivo de texto ASCII de 1 GB con 5 millones de líneas, en Python 3.3+ de 64 bits, el requisito de memoria máxima es de aproximadamente 2,3 GB para solo los bytes
objeto, la list
, y el str
individual s en la list
. Un programa que necesita 2,3 veces más RAM que el tamaño de los archivos que procesa no escalará a archivos grandes.
Para solucionarlo, cambie ese código original a:
file_content = io.TextIOWrapper(obj['Body'], encoding='utf-8')
for line in file_content:
Dado que obj['Body']
parece ser utilizable para transmisión perezosa
esto debería eliminar ambos copias de los datos completos del archivo de la memoria. Usando TextIOWrapper
significa obj['Body']
se lee con pereza y se decodifica en fragmentos (de unos pocos KB a la vez), y las líneas también se iteran con pereza; esto reduce las demandas de memoria a una cantidad pequeña y en gran medida fija (el costo máximo de la memoria dependería de la longitud de la línea más larga), independientemente del tamaño del archivo.
Actualización:
Se parece a StreamingBody
no implementa io.BufferedIOBase
A B C. Tiene su propia API documentada
sin embargo, eso puede usarse para un propósito similar. Si no puedes hacer el TextIOWrapper
haga el trabajo por usted (es mucho más eficiente y simple si se puede hacer que funcione), una alternativa sería hacer:
file_content = (line.decode('utf-8') for line in obj['Body'].iter_lines())
for line in file_content:
A diferencia de usar TextIOWrapper
, no se beneficia de la decodificación masiva de bloques (cada línea se decodifica individualmente), pero por lo demás debería lograr los mismos beneficios en términos de uso de memoria reducido.