import multiprocessing
import time
from subprocess import call,STDOUT
from glob import glob
import sys
def do_calculation(data):
x = time.time()
with open(data + '.classes.report','w') as f:
call(["external script", data], stdout = f.fileno(), stderr=STDOUT)
return 'apk: {data!s} time {tim!s}'.format(data = data ,tim = time.time()-x)
def start_process():
print 'Starting', multiprocessing.current_process().name
if __name__ == '__main__':
inputs = glob('./*.dex')
builtin_outputs = map(do_calculation, inputs)
print 'Built-in:'
for i in builtin_outputs:
print i
pool_size = multiprocessing.cpu_count() * 2
print 'Worker Pool size: %s' % pool_size
pool = multiprocessing.Pool(processes=pool_size,
initializer=start_process,
)
pool_outputs = pool.map(do_calculation, inputs)
pool.close() # no more tasks
pool.join() # wrap up current tasks
print 'Pool output:'
for i in pool_outputs:
print i
令人惊讶的是,builtin_outputs
的执行时间比pool_outputs
更短:
Built-in:
apk: ./TooDo_2.0.8.classes.dex time 5.69289898872
apk: ./TooDo_2.0.9.classes.dex time 5.37206411362
apk: ./Twitter_Client.classes.dex time 0.272782087326
apk: ./zaTelnet_Light.classes.dex time 0.141801118851
apk: ./Temperature_Converter.classes.dex time 0.270312070847
apk: ./Tipper_1.0.classes.dex time 0.293262958527
apk: ./XLive.classes.dex time 0.361288070679
apk: ./TwitterDroid_0.1.2_alpha.classes.dex time 0.381947040558
apk: ./Universal_Conversion_Application.classes.dex time 0.404763936996
Worker Pool size: 8
Pool output:
apk: ./TooDo_2.0.8.classes.dex time 5.72440505028
apk: ./TooDo_2.0.9.classes.dex time 5.9017829895
apk: ./Twitter_Client.classes.dex time 0.309305906296
apk: ./zaTelnet_Light.classes.dex time 0.374011039734
apk: ./Temperature_Converter.classes.dex time 0.450366973877
apk: ./Tipper_1.0.classes.dex time 0.379780054092
apk: ./XLive.classes.dex time 0.394504070282
apk: ./TwitterDroid_0.1.2_alpha.classes.dex time 0.505702018738
apk: ./Universal_Conversion_Application.classes.dex time 0.512043952942
答案 0 :(得分:4)
当您使用多处理时,您应该为工作进程提供足够的计算以持续至少几秒钟。如果工作进程结束得太快,则花费太多时间来设置池,生成子进程,并且(可能)在进程之间切换(并且实际执行预期计算的时间不够)以证明使用multiprocessing
是合理的。
此外,如果您有一个CPU绑定计算,那么使用比核心(multiprocessing.cpu_count()
)更多的进程初始化池会适得其反。它将使OS在进程之间切换,同时不允许计算更快地进行。
答案 1 :(得分:2)
如果“外部脚本”中涉及的工作负载足够IO,使其硬盘饱和,则并行运行多个副本只会减慢速度,因为从多个文件读取会产生额外的搜索。
如果您使CPU饱和并且没有多个CPU核心可用,也是如此。
答案 2 :(得分:1)
def do_calculation(data):
x = time.time()
with open(data + '.classes.report','w') as f:
call(["external script", data], stdout = f.fileno(), stderr=STDOUT)
return 'apk: {data!s} time {tim!s}'.format(data = data ,tim = time.time()-x)
您正在测量执行单个任务所需的时间。如果并行运行任务,则每个单独的任务都不会变短。相反,它们都在同一时间运行。换句话说,您正在测量这个错误,您应该计算所有任务的总时间而不是每个任务。
缓慢可能是因为同时运行各种任务会相互干扰,因此任务不会全速运行。