我正在尝试掌握 python 并行性。这是我正在使用的代码
import time
from concurrent.futures import ProcessPoolExecutor
def listmaker():
for i in xrange(10000000):
pass
#Without duo core
start = time.time()
listmaker()
end = time.time()
nocore = "Total time, no core, %.3f" % (end- start)
#with duo core
start = time.time()
pool = ProcessPoolExecutor(max_workers=2) #I have two cores
results = list(pool.map(listmaker()))
end = time.time()
core = "Total time core, %.3f" % (end- start)
print nocore
print core
我假设因为我使用两个核心,所以速度接近两倍。但是,当我大多数时候运行此代码时,nocore
输出比 core
输出更快。即使我改变也是如此
def listmaker():
for i in xrange(10000000):
pass
至
def listmaker():
for i in xrange(10000000):
print i
事实上,在某些运行中,无核心
运行速度更快。有人可以阐明这个问题吗?我的设置正确吗?我是不是做错了什么?
最佳答案
您错误地使用了pool.map()
。看看pool.map文档。它需要一个可迭代的参数,并且会将可迭代的每个项目单独传递到池中。由于您的函数仅返回 None
,因此它无事可做。但是,您仍然会产生产生额外进程的开销,这需要时间。
您对pool.map
的使用应该如下所示:
results = pool.map(function_name, some_iterable)
注意几件事:
- 由于您使用的是 print 语句而不是函数,因此我假设您使用的是某种 Python2 变体。在 Python2 中,
pool.map
无论如何都会返回一个列表。无需再次将其转换为列表。 - 第一个参数应该是函数名称不带括号。这标识了池工作人员应该执行的功能。当您包含括号时,该函数将在此处调用,而不是在池中。
pool.map
旨在对可迭代中的每个项目调用一个函数,因此您的测试用例需要创建一些可迭代以供其使用,而不是像您的那样不带参数的函数当前示例。
尝试使用函数的一些实际输入再次运行试验,并检索输出。这是一个例子:
import time
from concurrent.futures import ProcessPoolExecutor
def read_a_file(file_name):
with open(file_name) as fi:
text = fi.read()
return text
file_list = ['t1.txt', 't2.txt', 't3.txt']
#Without duo core
start = time.time()
single_process_text_list = []
for file_name in file_list:
single_process_text_list.append(read_a_file(file_name))
end = time.time()
nocore = "Total time, no core, %.3f" % (end- start)
#with duo core
start = time.time()
pool = ProcessPoolExecutor(max_workers=2) #I have two cores
multiprocess_text_list = pool.map(read_a_file, file_list)
end = time.time()
core = "Total time core, %.3f" % (end- start)
print(nocore)
print(core)
结果:
Total time, no core, 0.047
Total time core, 0.009
每个文本文件都有 150,000 行乱码。请注意,在并行处理值得之前必须完成多少工作。当我在每个文件中运行 10,000 行的试验时,单进程方法仍然更快,因为它没有产生额外进程的开销。但有这么多工作要做,额外的流程就变得值得付出努力。
顺便说一句,此功能可通过 multiprocessing pools 获得。在 Python2 中,因此如果您愿意,您可以避免从 future 导入任何内容。
关于python - 并行速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29178838/