Sto usando Python 2.6 su un Mac Mini con 1GB di RAM. Voglio leggere in un file di testo enormePython: Come leggere un enorme file di testo nella memoria
$ ls -l links.csv; file links.csv; tail links.csv
-rw-r--r-- 1 user user 469904280 30 Nov 22:42 links.csv
links.csv: ASCII text, with CRLF line terminators
4757187,59883
4757187,99822
4757187,66546
4757187,638452
4757187,4627959
4757187,312826
4757187,6143
4757187,6141
4757187,3081726
4757187,58197
Così ogni riga del file è costituito da una tupla di due separati da virgole valori interi. Voglio leggere l'intero file e ordinarlo secondo la seconda colonna. So che potrei fare l'ordinamento senza leggere l'intero file in memoria. Ma ho pensato per un file di 500 MB dovrei essere ancora in grado di farlo in memoria dato che ho 1 GB disponibile.
Tuttavia, quando provo a leggere il file, Python sembra allocare molta più memoria di quella richiesta dal file sul disco. Quindi, anche con 1 GB di RAM non riesco a leggere il file da 500 MB in memoria. Il mio codice Python per la lettura del file e la stampa alcune informazioni circa il consumo di memoria è:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
infile=open("links.csv", "r")
edges=[]
count=0
#count the total number of lines in the file
for line in infile:
count=count+1
total=count
print "Total number of lines: ",total
infile.seek(0)
count=0
for line in infile:
edge=tuple(map(int,line.strip().split(",")))
edges.append(edge)
count=count+1
# for every million lines print memory consumption
if count%1000000==0:
print "Position: ", edge
print "Read ",float(count)/float(total)*100,"%."
mem=sys.getsizeof(edges)
for edge in edges:
mem=mem+sys.getsizeof(edge)
for node in edge:
mem=mem+sys.getsizeof(node)
print "Memory (Bytes): ", mem
L'uscita ho ottenuto è stato:
Total number of lines: 30609720
Position: (9745, 2994)
Read 3.26693612356 %.
Memory (Bytes): 64348736
Position: (38857, 103574)
Read 6.53387224712 %.
Memory (Bytes): 128816320
Position: (83609, 63498)
Read 9.80080837067 %.
Memory (Bytes): 192553000
Position: (139692, 1078610)
Read 13.0677444942 %.
Memory (Bytes): 257873392
Position: (205067, 153705)
Read 16.3346806178 %.
Memory (Bytes): 320107588
Position: (283371, 253064)
Read 19.6016167413 %.
Memory (Bytes): 385448716
Position: (354601, 377328)
Read 22.8685528649 %.
Memory (Bytes): 448629828
Position: (441109, 3024112)
Read 26.1354889885 %.
Memory (Bytes): 512208580
Già dopo aver letto solo il 25% del file 500MB, Python consuma 500 MB. Quindi sembra che la memorizzazione del contenuto del file come una lista di tuple di ints non sia molto efficiente in termini di memoria. C'è un modo migliore per farlo, in modo che io possa leggere il mio file da 500 MB nel mio 1 GB di memoria?
Credo che con interprete, come Python, u non può davvero sapere dove sta andando la memoria. Tuttavia, le liste [di solito - non conosco l'esatta implementazione di Python) richiedono più memoria degli array, ad esempio per i puntatori prev/next. Probabilmente dovrai usare C/C++ per sapere esattamente quanta memoria usi. – Drakosha
si basa la stima della memoria sui dati grezzi, ma poi si creano tuple e int. Rispetto alle stringhe corte, l'overhead dell'istanza di Python è visibile qui come puoi vedere. Puoi ordinare questi dati anche come stringhe pure, hai provato? – u0b34a0f6ae
La mia stima della memoria aggiunge il consumo di memoria degli interi, delle tuple e della lista. È abbastanza ok, è più o meno lo stesso (meno la memoria consumata dall'interprete Python) come quello che vedo usando top. Ma non ho provato a ordinare i dati come stringhe pure. Come potrei farlo? – asmaier