Python多处理仅在第一次运行后快速

Python多处理仅在第一次运行后快速,python,python-3.x,python-multiprocessing,Python,Python 3.x,Python Multiprocessing,我有一个脚本,它使用多处理来打开~200k.csv文件并执行计算。以下是工作流程: 1) 考虑一个包含~200k.csv文件的文件夹。每个.csv文件包含以下内容: .csv文件示例: 2) 脚本将所有.csv文件的列表保存在list()中 3) 由于我有8个处理器可用,脚本将包含~200k.csv文件的列表分为8个列表 4) 该脚本调用do\u something\u和\u csv()8次,并并行执行计算 在线性模式下,执行大约需要4分钟 在并行和串行中,如果我第一次执行脚本,则需要更长的时间

我有一个脚本,它使用多处理来打开~200k.csv文件并执行计算。以下是工作流程:

1) 考虑一个包含~200k.csv文件的文件夹。每个.csv文件包含以下内容:

.csv文件示例: 2) 脚本将所有.csv文件的列表保存在
list()中

3) 由于我有8个处理器可用,脚本将包含~200k.csv文件的列表分为8个列表

4) 该脚本调用
do\u something\u和\u csv()
8次,并并行执行计算

在线性模式下,执行大约需要4分钟

在并行和串行中,如果我第一次执行脚本,则需要更长的时间。如果我执行第二次、第三次等,大约需要1分钟。python似乎正在缓存某种IO操作?这看起来像是因为我有一个进度条,例如,如果我一直执行到进度条为5k/200k并终止程序,下一次执行将非常快地通过前5k运行,然后减慢速度

Python版本:3.6.1

伪Python代码:
def multiproc_dispatch():
lst_of_all_csv_文件=获取_文件列表(“/path_to_csv_文件”)
分割的所有csv文件的列表=分割的列表块(所有csv文件的列表块,8)
经理=经理()
shared_dict=manager.dict()
工作=[]
对于分割的所有csv文件中的所有csv文件中的第一个文件:
p=进程(目标=使用csv做某事,参数=(共享的csv文件,所有csv文件的lst文件))
jobs.append(p)
p、 开始()
#等待工人完成
工作中的工作:
job.join()
def read_csv_文件(csv_文件):
lst_a=[]
lst_b=[]
打开(csv_文件,'r')作为f_读取:
csv_reader=csv.reader(f_read,分隔符=',')
对于csv_读取器中的行:
lst_a.append(float(行[0]))
lst_b.append(float(行[1]))
返回lst_a,lst_b
def do_something_与_csv(共享目录、所有_csv_文件的列表):
temp_dict=lambda:defaultdict(self.mydict)()
对于所有csv文件中的lst\U中的csv\U文件:
lst_a,lst_b=读取csv_文件(csv_文件)
临时目录[csv文件]=(第一个目录a、第二个目录b)
共享目录更新(临时目录)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
多进程调度()

这无疑是RAM缓存开始发挥作用,这意味着第二次加载文件会更快,因为数据已经在RAM中,而不是来自磁盘。(这里很难找到好的参考资料,欢迎任何帮助) 这与多处理无关,甚至与python本身无关


不相关,因为问题编辑我认为并行运行时代码持续时间较长的原因来自于从每个子流程中访问的
共享dict
变量(参见示例)。用python在进程之间创建和发送数据的速度很慢,应该减少到最低限度(在这里,每个作业可以返回一个dict,然后合并它们)。

这无疑是RAM缓存发挥作用,这意味着第二次加载文件的速度更快,因为数据已经在RAM中,而不是来自磁盘。(这里很难找到好的参考资料,欢迎任何帮助) 这与多处理无关,甚至与python本身无关


不相关,因为问题编辑我认为并行运行时代码持续时间较长的原因来自于从每个子流程中访问的
共享dict
变量(参见示例)。用python在进程之间创建和发送数据的速度很慢,应该减少到最小值(在这里,每个作业可以返回一个dict,然后合并它们)。

两次连续的线性运行都在4分钟左右吗?我刚刚做了比较,事实上,线性模式第二次运行后不到4分钟。你知道为什么吗?我终止了脚本,它不在同一执行的循环中。看到我下面的答案了吗?两次连续的线性运行都在4分钟左右?我刚刚进行了比较,事实上,在第二次运行线性模式后不到4分钟。你知道为什么吗?我终止了脚本,它不在同一执行的循环中。请参见下面的答案。我的共享dict已经在执行您在原始代码中提出的操作。也就是说,共享dict仅更新8次。。我会更新这个问题。我不明白如果我终止程序,对象怎么会在RAM上。我认为这可能与垃圾收集有关。好吧,按照你的说法。垃圾收集意味着你的RAM可以被其他程序自由使用;但是,操作系统不会“重置”它;如果不久后重新加载相同的文件,它仍将在缓存中。当然,这在python中是不可见的,但在操作系统级别上是可见的。这就是为什么ram监控工具有一个“缓存”类别。阅读更多关于RAM缓存的信息!我理解,但我觉得非常奇怪的是,我在监控RAM的使用情况,如果缓存了所有200k文件,RAM的使用量并没有增加。我甚至用5M.csv文件进行了测试,在第二次运行后,执行速度更快,RAM使用率始终不变;通常,几乎所有的空闲RAM都是从以前的计算中缓存出来的(不仅仅是从python中)。所以,也许你的新缓存只是删除了一些旧缓存(前提是你看的是缓存的ram而不是空闲的ram),这更有意义。谢谢。我的共享dict已经在执行您在原始代码中提出的操作。也就是说,共享dict仅更新8次。。我会更新这个问题。我不明白如果我终止程序,对象怎么会在RAM上。我认为这可能与垃圾收集有关。好吧,按照你的说法。垃圾收集意味着你的RAM可以被其他程序自由使用;但是,操作系统不会“重置”它;如果不久后重新加载相同的文件,它仍将在缓存中。当然,这在python中是不可见的,但在操作系统级别上是可见的。这就是为什么ram
0, 1
2, 3
4, 5
...
~500 rows