【发布时间】:2026-02-09 21:20:03
【问题描述】:
假设yo = Yo() 是一个带有double 方法的大对象,该方法返回其参数乘以2。
如果我将yo.double 传递给multiprocessing 的imap,那么它会非常慢,因为我认为每个函数调用都会创建yo 的副本。
也就是说,这很慢:
from tqdm import tqdm
from multiprocessing import Pool
import numpy as np
class Yo:
def __init__(self):
self.a = np.random.random((10000000, 10))
def double(self, x):
return 2 * x
yo = Yo()
with Pool(4) as p:
for _ in tqdm(p.imap(yo.double, np.arange(1000))):
pass
输出:
0it [00:00, ?it/s]
1it [00:06, 6.54s/it]
2it [00:11, 6.17s/it]
3it [00:16, 5.60s/it]
4it [00:20, 5.13s/it]
...
但是,如果我用函数 double_wrap 包装 yo.double 并将其传递给 imap,那么它基本上是瞬时的。
def double_wrap(x):
return yo.double(x)
with Pool(4) as p:
for _ in tqdm(p.imap(double_wrap, np.arange(1000))):
pass
输出:
0it [00:00, ?it/s]
1000it [00:00, 14919.34it/s]
包装函数如何以及为什么会改变行为?
我使用 Python 3.6.6。
【问题讨论】:
-
我的回答有什么不清楚的地方吗?
-
@Darkonaut 我只是不明白为什么制作功能模块级别会阻止对象的复制。毕竟,该函数需要有一个指向
yo对象本身的指针——这应该要求所有进程复制yo,因为它们不能共享内存。 -
我将我对上述评论的回复重新定位到我的答案中。
标签: python parallel-processing multiprocessing