为了确定使用了大部分计算时间的步骤,我运行了cProfile,得到了以下结果。
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.014 0.014 216.025 216.025 func_poolasync.py:2(<module>)
11241 196.589 0.017 196.589 0.017 {method 'acquire' of 'thread.lock' objects}
982 0.010 0.000 196.532 0.200 threading.py:309(wait)
1000 0.002 0.000 196.498 0.196 pool.py:565(get)
1000 0.005 0.000 196.496 0.196 pool.py:557(wait)
515856/3987 0.350 0.000 13.434 0.003 artist.py:230(stale)
花费了大部分时间的步骤显然是: method 'acquire' of 'thread.lock' objects
. 我没有使用线程,而是使用了 pool.apply_async
与几个处理器,所以我很困惑为什么 thread.lock
是问题所在?
我希望能得到一些启示,为什么会出现这样的瓶颈?以及如何把这个时间降下来?
下面是代码的样子。
path='/usr/home/work'
filename='filename'
with open(path+filename+'/'+'result.pickle', 'rb') as f:
pdata = pickle.load(f)
if __name__ == '__main__':
pool = Pool()
results=[]
data=list(range(1000))
print('START')
start_time = int(round(time.time()))
result_objects = [pool.apply_async(func, args=(nomb,pdata[0],pdata[1],pdata[2])) for nomb in data]
results = [r.get() for r in result_objects]
pool.close()
pool.join()
print('END', int(round(time.time()))-start_time)
修订:
通过切换 pool.apply_async
到 pool.map
我能够减少约3倍的执行时间。
输出。
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.113 0.113 70.824 70.824 func.py:2(<module>)
4329 28.048 0.006 28.048 0.006 {method 'acquire' of 'thread.lock' objects}
4 0.000 0.000 28.045 7.011 threading.py:309(wait)
1 0.000 0.000 28.044 28.044 pool.py:248(map)
1 0.000 0.000 28.044 28.044 pool.py:565(get)
1 0.000 0.000 28.044 28.044 pool.py:557(wait)
修改代码。
if __name__ == '__main__':
pool = Pool()
data=list(range(1000))
print('START')
start_time = int(round(time.time()))
funct = partial(func,pdata[0],pdata[1],pdata[2])
results = pool.map(funct,data)
print('END', int(round(time.time()))-start_time)
但是,我们发现 一些 的迭代导致了无意义的结果。我不知道为什么会出现这种情况,但是,可以看到'方法'获取'线程.锁'对象'仍然是决定速率的步骤。
剖析器只告诉你主进程在做什么,而它的子进程在做所有的工作。
来源:/stackover https:/stackoverflow.coma225306651064565。