En betydelig besparelse kan opnås ved at undgå at slurre hele din inputfil i hukommelsen som en list af linjer.
Specifikt er disse linjer forfærdelige med hensyn til hukommelsesbrug, idet de involverer en maksimal hukommelsesbrug på bytes objekt størrelsen af hele din fil, plus en list af linjer med det komplette indhold af filen også:
file_content = obj['Body'].read().decode('utf-8').splitlines(True)
for line in file_content:
For en 1 GB ASCII-tekstfil med 5 millioner linjer, på 64 bit Python 3.3+, er det et maksimalt hukommelseskrav på ca. 2,3 GB for kun bytes objekt, list , og den individuelle str s på list . Et program, der har brug for 2,3 gange så meget RAM som størrelsen af de filer, det behandler, skaleres ikke til store filer.
For at rette, skal du ændre den originale kode til:
file_content = io.TextIOWrapper(obj['Body'], encoding='utf-8')
for line in file_content:
I betragtning af at obj['Body'] ser ud til at kunne bruges til dovne streaming
dette burde fjerne begge kopier af de komplette fildata fra hukommelsen. Brug af TextIOWrapper betyder obj['Body'] læses dovent og afkodes i bidder (af nogle få KB ad gangen), og linjerne gentages også dovent; dette reducerer hukommelsesbehovet til et lille, stort set fast beløb (den maksimale hukommelsesomkostning vil afhænge af længden af den længste linje), uanset filstørrelsen.
Opdatering:
Det ligner StreamingBody implementerer ikke io.BufferedIOBase ABC. Den har sin egen dokumenterede API
det kan dog bruges til et lignende formål. Hvis du ikke kan lave TextIOWrapper gøre arbejdet for dig (det er meget mere effektivt og enkelt, hvis det kan fås til at fungere), et alternativ ville være at gøre:
file_content = (line.decode('utf-8') for line in obj['Body'].iter_lines())
for line in file_content:
I modsætning til at bruge TextIOWrapper , den har ikke gavn af masseafkodning af blokke (hver linje afkodes individuelt), men ellers skulle den stadig opnå de samme fordele i form af reduceret hukommelsesforbrug.