数组的文件数据占用大量内存

2024-09-30 20:37:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用一个带有制表符分隔值的大文本文件,并将它们添加到数组中。在

当我在一个32MB的文件上运行代码时,python的内存消耗非常大;使用了大约500MB的RAM。在

我需要能够运行一个2GB的文件,甚至更大的文件代码。在

我目前的代码是:

markers = []

def parseZeroIndex():
    with open('chromosomedata') as zeroIndexes:
        for line in zeroIndexes:
            markers.append(line.split('\t'))

parseZeroIndex()

对我的2GB文件运行此代码是不可能的。文件如下所示:

^{pr2}$

我的问题是:

什么在使用这些记忆?在

什么是更有效的方法来做这种记忆明智?在


Tags: 文件记忆内存代码defwithline数组
1条回答
网友
1楼 · 发布于 2024-09-30 20:37:10

“怎么会用这么多内存?”在

Python对象有开销。查看某些字符串实际占用的字节数:

Python 2:

>>> import sys
>>> map(sys.getsizeof, ('', 'a', u'ä'))
[21, 22, 28]

Python 3:

^{pr2}$

“什么是更有效的方法来做这种记忆智慧?”在

在注释中,您说有很多重复值,因此string interning(只存储每个不同字符串值的一个副本)可能会有很大帮助。试试这个:

Python 2:

            markers.append(map(intern, line.rstrip().split('\t')))

Python 3:

            markers.append(list(map(sys.intern, line.rstrip().split('\t'))))

注意我还使用了line.rstrip()从行中删除尾随的\n。在


实验

我试过了

>>> x = [str(i % 1000) for i in range(10**7)]

以及

>>> import sys
>>> x = [sys.intern(str(i % 1000)) for i in range(10**7)]

在python3中。第一个占用355 MB(在Windows任务管理器中查看进程)。第二个只需要47MB。此外:

>>> sys.getsizeof(x)
40764032
>>> sum(map(sys.getsizeof, x[:1000]))
27890

因此,40MB用于引用字符串的列表(这并不奇怪,因为有1000万个引用,每个引用4个字节)。而字符串本身总共只有27KB


进一步改进

正如在实验中看到的,大部分RAM使用可能不是来自字符串,而是来自列表对象。您的markers列表对象以及所有表示行的列表对象。尤其是如果你使用64位的Python,我想你是这样做的。在

为了减少这种开销,可以使用元组而不是列表来表示行,因为它们更轻量级:

sys.getsizeof(['a', 'b', 'c'])
48
>>> sys.getsizeof(('a', 'b', 'c'))
40

我估计您的2GB文件有8000万行,这样可以节省640MB内存。如果运行64位Python,可能会更多。在

另一个想法是:如果所有行都有相同数量的值(我假设是三个),那么您可以丢弃8000万个行列表对象,而使用包含2.4亿个字符串值的一维列表。您只需使用markers[3*i+j]而不是markers[i][j]来访问它。它可以节省几GB的内存。在

相关问题 更多 >