我试图处理将大量腌制数据分小块写入磁盘的问题。这是示例代码:
from cPickle import *
from gc import collect
PATH = r'd:\test.dat'
@profile
def func(item):
for e in item:
f = open(PATH, 'a', 0)
f.write(dumps(e))
f.flush()
f.close()
del f
collect()
if __name__ == '__main__':
k = [x for x in xrange(9999)]
func(k)
open() 和 close() 放置在循环内,以排除内存中数据积累的可能原因。
为了说明问题,我附上了使用 Python 3d 方模块memory_profiler获得的内存分析结果:
Line # Mem usage Increment Line Contents
==============================================
14 @profile
15 9.02 MB 0.00 MB def func(item):
16 9.02 MB 0.00 MB path= r'd:\test.dat'
17
18 10.88 MB 1.86 MB for e in item:
19 10.88 MB 0.00 MB f = open(path, 'a', 0)
20 10.88 MB 0.00 MB f.write(dumps(e))
21 10.88 MB 0.00 MB f.flush()
22 10.88 MB 0.00 MB f.close()
23 10.88 MB 0.00 MB del f
24 collect()
在循环执行期间,会出现奇怪的内存使用量增长。怎样才能消除?有什么想法吗?
当输入数据量增加时,这些附加数据的量可以增长到比输入大得多的大小(更新:在实际任务中,我得到 300+Mb)
还有更广泛的问题——有哪些方法可以在 Python 中正确处理大量 IO 数据?
upd: 我重写了只留下循环体的代码,以查看具体何时发生增长,结果如下:
Line # Mem usage Increment Line Contents
==============================================
14 @profile
15 9.00 MB 0.00 MB def func(item):
16 9.00 MB 0.00 MB path= r'd:\test.dat'
17
18 #for e in item:
19 9.02 MB 0.02 MB f = open(path, 'a', 0)
20 9.23 MB 0.21 MB d = dumps(item)
21 9.23 MB 0.00 MB f.write(d)
22 9.23 MB 0.00 MB f.flush()
23 9.23 MB 0.00 MB f.close()
24 9.23 MB 0.00 MB del f
25 9.23 MB 0.00 MB collect()
似乎 dumps() 吃掉了内存。(虽然我实际上认为它会是 write())