【发布时间】:2019-01-05 08:51:35
【问题描述】:
我有一个执行以下操作的函数:
- 将文件作为输入并进行基本清理。
- 从文件中提取所需的项目,然后将它们写入 pandas 数据帧。
- dataframe最终转换成csv并写入文件夹。
这是示例代码:
def extract_function(filename):
with open(filename,'r') as f:
input_data=f.readlines()
try:
// some basic searching pattern matching extracting
// dataframe creation with 10 columns and then extracted values are filled in
empty dataframe
// finally df.to_csv()
if __name__ == '__main__':
pool_size = multiprocessing.cpu_count()
filenames=os.listdir("/home/Desktop/input")
pool=multiprocessing.Pool(pool_size)
pool.map(extract_function,filenames)
pool.close()
pool.join()
input 文件夹中的文件总数为4000。我使用了多处理,因为使用 for 循环 正常运行程序需要一些时间。以下是两种方法的执行时间:
正常 CPU 处理 = 139.22 秒
多处理 = 18.72 秒
我的系统规格是:
英特尔 i5 第 7 代,12gb 内存,1Tb 硬盘,Ubuntu 16.04
在为 4000 个文件运行程序时,所有核心都得到了充分利用(平均每个核心大约 90%)。所以我决定增加文件大小并重复这个过程。这次输入文件号从4000 增加到1,20,000。但是这次在运行代码时,CPU 使用率在启动时不稳定,一段时间后利用率下降(每个核心的平均使用率约为 10%)。 ram 利用率也很低,平均为 4gb 最大值(剩余 8gb 空闲)。使用 4000 个文件作为输入,写入 csv 的文件的速度很快,因为我可以看到一个跳跃或大约 1000 个文件或更多文件。但是以 1,20,000 个文件作为输入,文件写入速度减慢到大约 300 个文件,并且这种减慢呈线性增长,一段时间后文件写入速度瞬间变为 50-70 左右。一直以来,大部分 ram 都是免费的。我重新启动机器并尝试清除任何不需要的僵尸进程,但结果仍然相同。
这是什么原因? 我怎样才能对大文件实现相同的多处理?
注意:
* 每个文件大小平均约为 300kb。
* 每个正在写入的输出文件大约为 200 字节。
* 文件总数为 4080。因此总大小约为 1.2gb。
* 相同的 4080 个文件用于制作副本以获得 1,20,000 个文件。
* 这个程序是一个检查大量文件的多处理的实验。
更新 1
我在功能更强大的机器上尝试了相同的代码。
英特尔 i7 第 8 代 8700、1Tb SSHD 和 60gb 内存。
。文件写入比普通硬盘快得多。该计划采取:
- 对于 4000 个文件 - 3.7 秒
- 1,20,000 个文件 - 2 分钟
在实验过程中的某个时间点,我得到了最快的完成时间,即 84 秒。在那个时间点,它给了我一致的结果,同时连续尝试了两次。认为可能是因为我在池大小中正确设置了线程因子的数量,我重新启动并再次尝试。但这一次速度慢了很多。从一个角度来看,在正常运行期间,大约 3000-4000 个文件将在一两秒内写入,但这次它在一秒钟内写入低于 600 个文件。在这种情况下,也根本没有使用 ram。 即使使用了多处理模块,CPU 的平均利用率也只有 3-7% 左右。
【问题讨论】:
-
我可以推测,但您能否分享
extract_function并提供有关每个文件大小的更多详细信息?当您说input file size was increased from 4000 to 120000时,您是指文件总数还是单个文件大小?精神力量暗示 -
@selbie 已编辑,请检查
-
@selbie : 并行文件打开/读取是否使其变慢?如果那为什么它适用于 4000 个文件?有没有门槛之类的东西?
-
显而易见的事情是将
pool_size增加两到三倍。由于大多数情况下,您的代码可能会在 I/O 上被阻塞,因此您可以增加线程数。 -
相信我,当我这么说的时候,优化代码中任何内容的第一步是衡量它并了解性能瓶颈的实际位置。处理数据的 CPU 时间量很可能与花费在 I/O 上的时间量相比可以忽略不计。如果是这样的话,GPU 就没有多大帮助了。
标签: python pandas parallel-processing multiprocessing python-multiprocessing