Я использую Python 2.6 на Mac Mini с 1 ГБ оперативной памяти. Я хочу, чтобы прочитать в огромном текстовом файлеPython: как читать огромный текстовый файл в памяти
$ 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
Таким образом, каждая строка в файле состоит из набора из двух разделенных запятыми целочисленных значений. Я хочу прочитать весь файл и отсортировать его по второму столбцу. Я знаю, что я мог бы сортировать, не читая весь файл в памяти. Но я думал, что для файла размером 500 МБ я все равно могу сделать это в памяти, так как у меня есть 1 ГБ.
Однако, когда я пытаюсь прочитать в файле, Python, похоже, выделяет намного больше памяти, чем требуется файлу на диске. Поэтому даже с 1 ГБ оперативной памяти я не могу читать в 500 МБ файл в памяти. Моего код Python для чтения файла и печатей информации о потреблении памяти является:
#!/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
Выхода я получил:
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
Уже после прочтения только 25% файл 500MB, Python потребляет 500 МБ. Похоже, что сохранение содержимого файла в виде списка кортежей ints не очень эффективно. Есть ли лучший способ сделать это, чтобы я мог читать в своем 500 МБ файле в 1 ГБ памяти?
Я думаю, с переводчиком, как Python, и не может действительно знать, где будет память. Однако списки [обычно - я не знаю точной реализации python) требуют больше памяти, чем массивы, например, для prev/next указателей. Возможно, вам понадобится использовать C/C++, чтобы точно знать, сколько памяти вы используете. – Drakosha
вы основываете свою оценку памяти на необработанных данных, но затем создаете кортежи и ints. По сравнению с короткими строками, накладные расходы экземпляра Python примечательны здесь, как вы можете видеть. Вы можете сортировать эти данные, даже как чистые строки, вы пробовали это? – u0b34a0f6ae
Моя оценка памяти добавляет потребление памяти для ints, кортежей и списка. Это нормально, это примерно то же самое (минус память, потребляемая интерпретатором Python), как то, что я вижу с помощью top. Но я не пытался сортировать данные как чистые строки. Как мне это сделать? – asmaier