并行速度

Parallelism Speed

我正在尝试处理 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

事实上,在某些 运行 中,no core 运行 更快。有人可以阐明这个问题吗?我是我的设置正确吗?我是不是做错了什么?

您使用 pool.map() 不正确。查看 pool.map 文档。它需要一个可迭代的参数,并且它会将可迭代的每个项目单独传递到池中。由于您的函数只有 returns None,因此它无事可做。但是,您仍然会产生额外进程的开销,这需要时间。

您对 pool.map 的用法应如下所示:

results = pool.map(function_name, some_iterable)

注意几件事:

  • 由于您使用的是 print 语句而不是函数,我假设您使用的是某些 Python2 变体。在Python2、pool.map、returns反正一个列表。无需再次将其转换为列表。
  • 第一个参数应该是函数名不带括号。这标识池工作人员应执行的功能。当你包含括号时,函数就在那里被调用,而不是在池中。
  • 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 行的试验时,单进程方法仍然更快,因为它没有产生额外进程的开销。但是有了那么多工作要做,额外的过程就变得值得了。

顺便说一下,此功能在 Python2 中的 multiprocessing pools 中可用,因此如果您愿意,可以避免从 futures 导入任何内容。