我正在解析一些 XML 并根据当前正在处理的 XML 元素将数据写入不同的文件。处理元素非常快,写入数据也非常快。因此,文件需要经常打开和关闭。例如,给定一个巨大的文件
:
for _, node in lxml.etree.iterparse(file):
with open(f"{node.tag}.txt", 'a') as fout:
fout.write(node.attrib['someattr']+'\n'])
这可行,但相对而言,打开和关闭文件会花费大量时间。 (注意:这是一个玩具程序。实际上,我写入文件的实际内容以及文件名都是不同的。有关数据详细信息,请参阅最后一段。)
替代方案可能是:
fhs = {}
for _, node in lxml.etree.iterparse(file):
if node.tag not in fhs:
fhs[node.tag] = open(f"{node.tag}.txt", 'w')
fhs[node.tag].write(node.attrib['someattr']+'\n'])
for _, fh in fhs.items(): fh.close()
这将使文件保持打开状态,直到 XML 解析完成。有一点查找开销,但与迭代打开和关闭文件相比,这应该是最小的。
我的问题是,这种方法在性能方面有什么缺点?我知道这将使其他进程无法访问打开的文件,并且您可能会遇到 a limit of open files 。然而,我对性能问题更感兴趣。保持所有文件句柄打开是否会产生某种内存问题或处理问题?在这种情况下,可能会发生过多的文件缓冲?我不确定,所以这个问题。
输入 XML 文件最大可达 70GB 左右。生成的文件数量限制在 35 个左右,这与我在上述帖子中读到的限制相去甚远。
最佳答案
您已经提到的明显缺点是,需要大量内存来保持所有文件句柄打开,当然取决于文件的数量。这是您必须自己进行的计算。并且不要忘记写锁。
否则的话,这并没有太大的错误,但采取一些预防措施会很好:
fhs = {}
try:
for _, node in lxml.etree.iterparse(file):
if node.tag not in fhs:
fhs[node.tag] = open(f"{node.tag}.txt", 'w')
fhs[node.tag].write(node.attrib['someattr']+'\n'])
finally:
for fh in fhs.values(): fh.close()
注意:
当在 python 中循环字典时,你得到的项目实际上只是键。我建议执行 for key, item in d.items():
或 for item in d.values():
关于python - 保持文件句柄打开的缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51026191/