【发布时间】:2020-04-10 21:25:23
【问题描述】:
我有许多大型 csv 文件(每个约 400 MB,需要处理数千个,每个程序执行至少一百个)在每行的第一个单元格中包含长字符串(每行大约 100-300 个字符 1每个文件百万行),我的 Python 程序检查子字符串是否在给定的字符串中。如果是这样,那么我将包含该字符串的行附加到一个列表中,以便在处理完所有输入文件后存储在另一个系列的 csv 文件中。对于前十几个输入文件,程序以每个文件大约 20 秒的速度运行,我对此感到满意。
代码的相关部分(字符串处理循环)如下所示:
check = set(['a','b','c'])
storage = []
data = glob.glob('data_address/*.csv')
for raw_file in data:
read_file = open(raw_file,'r',newline='',encoding='utf-8')
list_file = list(csv.reader((line.replace('\0','') for line in read_file), delimiter=","))
row_count = sum(1 for row in list_file)
for i in range(1, row_count);
text = set(list_file[i][0].split())
if len(check.intersection(text)) > 0:
storage.append(list_file[i])
问题是随着处理的输入文件数量的增加,我开始有某些文件需要超过 20 秒的时间。此外,处理这些异常需要的时间越来越长——第一个异常需要大约 50 秒来处理,在循环结束时,异常可能需要数千秒来处理,这表明问题出在循环本身而不是任何个人档案。就字符串匹配的数量而言,这些异常与其他文件没有明显不同。
我不明白的是处理时间的增加并不一致。在每个异常之间我仍然有很多 20 秒的文件,所以不能说程序只是随着内存存储的增加而变慢。有谁知道发生了什么? cProfile 无法显示任何可能导致问题的组件。
我在 Windows 10 上使用 64 位 Python 3.8 和 1TB 硬盘,大约 10,000 MB 活动内存。
【问题讨论】:
-
@barny 感谢您的反馈。我已经相应地编辑了我的帖子。
-
在您共享的代码中,您并没有关闭文件。你真的应该使用上下文管理器,它们很棒。你能提供一个minimal reproducible example吗?我可以看到一些可以重构的东西,但是当我无法运行代码时很难做到。此外,虽然它可能无法解释手头的特定问题,但此代码存在许多低效方面。
-
这是使用 csv 的一种相当不寻常的方式。您是否尝试过更传统的方法?查看文档docs.python.org/3/library/csv.html。但如果是特定文件有问题,那么通用代码不是问题:,这些文件有什么不同?
-
某人,显然是“上帝”,删除了我的评论:展示自己,“上帝”:你为什么这样做?
-
@amc 虽然我同意 OP 应该使用
with,但当read_file被分配一个新的打开文件时,文件将在每次循环中关闭。更可能的问题是,list_file被存储引用,这只会增加内存使用量。
标签: python performance loops debugging memory