我观察到在Python 3.5 和Python 2.7 之间启动一系列流程的重要时间增量。
在下面的代码中,如果CRITICAL = 8:perf在Py2和Py3(<1s)中几乎相同。但对于9+,Py2中的perf保持不变,而在Py3中,它最差(~1min!)。
似乎与我给过程的args的大小有关...
更新: 它也链接到模块的位置。实际上,如果它是从“C:\”(或短路径)运行,那么Py3类似于Py2。但是如果从非常长的路径运行,Py3中的perf非常降级,而在Py2中则保持不变。
{{1}}
答案 0 :(得分:1)
我找到了一个替代方案,对于“多进程”工作而言似乎非常模块化。 通过这种方式,在Py3中,启动N进程的时间与Py2类似。
我没有为每个进程提供巨大的args,而是创建了一个链接到BaseManager的共享对象,其中一个i存储了进程所需的大量数据。 此外,我还可以存储共享进度或每个进程计算的任何数据,以便继续使用它。我真的很喜欢这个解决方案。
这里是代码:
from __future__ import print_function
import time
import itertools
from multiprocessing import Process
from multiprocessing.managers import BaseManager
def workerTask(sharedSandbox):
inputs = sharedSandbox.getARGS()
for _ in itertools.product(*inputs):
pass
class _SharedData(object):
def __init__(self, data):
self.__myARGS = data
def getARGS(self):
return self.__myARGS
class _GlobalManager(BaseManager):
BaseManager.register('SharedData', _SharedData)
if __name__ == '__main__':
CRITICAL = 9 # OK for 8-, KO for 9+
start = time.time()
manager = _GlobalManager()
manager.start()
ARGS = manager.SharedData([["123.4567{}".format(i) for i in range(CRITICAL)] for _ in range(10)])
workerPool = [Process(target=workerTask, args=(ARGS,)) for _ in range(15)]
for idx, w in enumerate(workerPool):
print("...Starting process #{} after {}".format(idx + 1, time.time() - start))
w.start()
print("ALL PROCESSES STARTED in {}!".format(time.time() - start))
while any([w.is_alive() for w in workerPool]):
pass