Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:写入文件时的内存使用情况(生成器与列表)_Python_List_Memory Management_Generator - Fatal编程技术网

Python:写入文件时的内存使用情况(生成器与列表)

Python:写入文件时的内存使用情况(生成器与列表),python,list,memory-management,generator,Python,List,Memory Management,Generator,我试图从一个大的tarball文件创建一个文件名列表,我想了解为什么在我的示例中内存使用率仍然相同?是因为f.write()在文件实际关闭之前仍在保存/缓冲内存中的所有对象吗?有没有办法改善这一点 # touch file{1..100000}.txt # tar cf test.tar file* 生成器 # python test.py Memory (Before): 40.918MB Memory (After): 117.066MB It took 12.6369504928588

我试图从一个大的tarball文件创建一个文件名列表,我想了解为什么在我的示例中内存使用率仍然相同?是因为
f.write()
在文件实际关闭之前仍在保存/缓冲内存中的所有对象吗?有没有办法改善这一点

# touch file{1..100000}.txt
# tar cf test.tar file*
生成器

# python test.py 
Memory (Before): 40.918MB
Memory (After): 117.066MB
It took 12.636950492858887 seconds.
列表:

# python test.py
Memory (Before): 40.918MB
Memory (After): 117.832MB
It took 12.049121856689453 seconds.
test.py

#!/usr/bin/python3

import memory_profiler
import tarfile
import time


def files_generator(tar):
    entry = tar.next()
    while entry:
        yield entry.name
        entry = tar.next()

def files_list(tar):
    return tar.getnames()

if __name__ == '__main__':
    print(f'Memory (Before): {memory_profiler.memory_usage()[0]:.3f}MB')
    start = time.time()
    tar = tarfile.open('test.tar')
    with open('output_g.txt', 'w') as f:
        for i in files_generator(tar):
        #for i in files_list(tar):
            f.write(i + '\n')
    end = time.time()
    print(f'Memory (After): {memory_profiler.memory_usage()[0]:.3f}MB')
    print(f'It took {end-start} seconds.')
Tarfile.next()
方法缓存其内容:


结果是
Tarfile.getnames()
调用
Tarfile.getmembers()
调用
Tarfile.getmembers()。\u load()
重复调用
Tarfile.next()
,直到所有内容都读入
self.members
。因此
Tarfile.getnames()
和通过
Tarfile.next()
进行迭代将具有相同的内存使用率。

您是否尝试过刷新磁盘?@HTF:如果您想避免此问题,请使用子类重写
Tarfile.next()
方法并停止缓存。只需从现有类中的方法复制代码,并省略有问题的行。请注意,这将完全破坏
Tarfile
,除了您的预期用途(因为所有内容都使用
next()
)。
if tarinfo is not None: 
    self.members.append(tarinfo)