【发布时间】:2010-12-26 04:24:05
【问题描述】:
我在具有 1GB RAM 的 Mac Mini 上使用 Python 2.6。我想读一个巨大的文本文件
$ 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
所以文件中的每一行都包含一个由两个逗号分隔的整数值组成的元组。 我想读入整个文件并根据第二列对其进行排序。我知道,我可以在不将整个文件读入内存的情况下进行排序。但我认为对于 500MB 的文件,我应该仍然能够在内存中执行它,因为我有 1GB 可用。
但是,当我尝试读取文件时,Python 分配的内存似乎比磁盘上文件所需的内存要多得多。因此,即使有 1GB 的 RAM,我也无法将 500MB 的文件读入内存。 我用于读取文件并打印有关内存消耗的一些信息的 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
在仅读取 500MB 文件的 25% 之后,Python 已经消耗了 500MB。因此,将文件内容存储为整数元组列表似乎不是很有效的内存。 有没有更好的方法可以将 500MB 的文件读入 1GB 的内存?
【问题讨论】:
-
我猜使用解释器,比如 Python,你无法真正知道内存在哪里。但是,列表 [通常 - 我不知道确切的 python 实现)比数组需要更多的内存,例如用于 prev/next 指针。您可能需要使用 C/C++ 才能准确了解您使用了多少内存。
-
您将内存估计基于原始数据,然后创建元组和整数。如您所见,与短字符串相比,Python 的实例开销在这里很明显。您甚至可以将这些数据排序为纯字符串,您尝试过吗?
-
我的内存估计加上整数、元组和列表的内存消耗。没关系,它与我使用 top 看到的大致相同(减去 Python 解释器消耗的内存)。但我没有尝试将数据排序为纯字符串。我该怎么做?
-
按字母顺序对字符串进行排序会产生错误的结果。您是否尝试过 jsut 获得 4GB RAM?它可能会起作用,如果您经常处理这种大小的数据,它很快就会收回成本。
-
在内存中排序有什么意义?在不将整个文件加载到内存的情况下进行排序,你就完成了!当文件增长时,或者当你需要你的程序在更小的设备(电话,任何人?)上运行时,它就会起作用。如果您的目标只是试图了解 Python 本身的内存使用情况,那么请编写另一个更明确的问题!
标签: python memory sorting large-files