返回的imap_unordered
迭代器的结果排序是任意的,它似乎没有imap
(我使用下面的代码检查)运行得更快,所以为什么要使用这种方法?
from multiprocessing import Pool
import time
def square(i):
time.sleep(0.01)
return i ** 2
p = Pool(4)
nums = range(50)
start = time.time()
print 'Using imap'
for i in p.imap(square, nums):
pass
print 'Time elapsed: %s' % (time.time() - start)
start = time.time()
print 'Using imap_unordered'
for i in p.imap_unordered(square, nums):
pass
print 'Time elapsed: %s' % (time.time() - start)
答案 0 :(得分:32)
使用pool.imap_unordered
代替pool.imap
不会对代码的总运行时间产生很大影响。它可能会快一点,但不会太多。
然而,它可能会使迭代中可用的值之间的间隔更均匀。也就是说,如果您的操作可能需要非常不同的时间(而不是您在示例中使用的一致0.01
秒),imap_unordered
可以通过提前更快计算的值来平滑事物计算速度较慢的值。常规imap
将延迟产生更快的速度,直到计算出它们之前的较慢速度(但这不会延迟工作进程继续进行更多计算,只是你看到它们的时间)。 / p>
尝试让您的工作函数在i*0.1
秒内休眠,改变输入列表并在循环中打印i
。您将能够看到两个imap
版本之间的差异。这是我的版本(main
函数和if __name__ == '__main__'
样板是在Windows上正确运行所必需的):
from multiprocessing import Pool
import time
import random
def work(i):
time.sleep(0.1*i)
return i
def main():
p = Pool(4)
nums = range(50)
random.shuffle(nums)
start = time.time()
print 'Using imap'
for i in p.imap(work, nums):
print i
print 'Time elapsed: %s' % (time.time() - start)
start = time.time()
print 'Using imap_unordered'
for i in p.imap_unordered(work, nums):
print i
print 'Time elapsed: %s' % (time.time() - start)
if __name__ == "__main__":
main()
imap
版本会有很长的暂停,而像49这样的值正在处理(需要4.9秒),然后它会飞过一堆其他值(在我们等待时由其他进程计算出来) 49待处理)。相反,imap_unordered
循环通常不会一次暂停。它会有更频繁但更短暂的停顿,并且它的输出会更顺畅。
答案 1 :(得分:5)
imap_unordered似乎也比imap使用更少的内存。至少这是我在数百万事物上使用迭代器所经历的事情。