python - 保持文件句柄打开的缺点?

标签 python python-3.x performance file-handling

我正在解析一些 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/

相关文章:

python - 页面的链接和该子页面的链接。递归/线程

performance - 找到可以从 1 到 99 美分的任何零钱所需的最少硬币数

java - 如何以编程方式测量请求的成本(cpm_usd)?

python - ChainMap.new_child() 返回什么?

python - 将函数与笔记本目录中其他 python 文件中的变量一起使用

python-3.x - pandas groupby apply 不会广播到 DataFrame

python - 使用 python3 而不是 python 运行 Flask

php - 为什么 PHP 函数 imap_search() 很慢?

c++ - C++中的分页效果是什么?

python - 随机选择 DataFrame 中列应切换值的行