【发布时间】:2016-01-28 12:54:07
【问题描述】:
考虑以下函数:
def f(x, dummy=list(range(10000000))):
return x
如果我使用multiprocessing.Pool.imap,我会得到以下时间:
import time
import os
from multiprocessing import Pool
def f(x, dummy=list(range(10000000))):
return x
start = time.time()
pool = Pool(2)
for x in pool.imap(f, range(10)):
print("parent process, x=%s, elapsed=%s" % (x, int(time.time() - start)))
parent process, x=0, elapsed=0
parent process, x=1, elapsed=0
parent process, x=2, elapsed=0
parent process, x=3, elapsed=0
parent process, x=4, elapsed=0
parent process, x=5, elapsed=0
parent process, x=6, elapsed=0
parent process, x=7, elapsed=0
parent process, x=8, elapsed=0
parent process, x=9, elapsed=0
现在如果我使用functools.partial 而不是使用默认值:
import time
import os
from multiprocessing import Pool
from functools import partial
def f(x, dummy):
return x
start = time.time()
g = partial(f, dummy=list(range(10000000)))
pool = Pool(2)
for x in pool.imap(g, range(10)):
print("parent process, x=%s, elapsed=%s" % (x, int(time.time() - start)))
parent process, x=0, elapsed=1
parent process, x=1, elapsed=2
parent process, x=2, elapsed=5
parent process, x=3, elapsed=7
parent process, x=4, elapsed=8
parent process, x=5, elapsed=9
parent process, x=6, elapsed=10
parent process, x=7, elapsed=10
parent process, x=8, elapsed=11
parent process, x=9, elapsed=11
为什么使用functools.partial的版本慢了这么多?
【问题讨论】:
-
你为什么使用
list(range(...))? AFAIK 你的代码在没有调用list的情况下会做同样的事情,除了ShadowRanger 解释的问题不会发生并且酸洗的开销会小得多小。 -
旁注:使用
lists(或任何其他可变类型)作为默认(或partial绑定)参数是危险的,因为 samelist在函数的所有默认调用之间共享,而不是每次调用的新副本;通常,您需要新鲜的副本。 -
顺便说一句,使用可变对象作为默认值通常是个坏主意,因为如果你在函数中修改它,每次后续调用函数都会看到变化
-
@Bakuriu:我认为这只是一个演示差异的最小示例,而不是真实代码。值得赞赏;得到某人的项目的巨大转储并且没有迹象表明他们试图解决这个问题是皇家 PITA。
标签: python python-3.x python-multiprocessing functools