我创建了一个比单进程慢的multiproc函数
for n in range(nombre_de_cycles):
debut = time.time()
paris.reveil_multiproc(2)
duree = time.time() - debut
print((n, duree), end=",")
给出:
(0, 13.04754900932312),(1, 11.9977388381958),(2, 12.56324291229248),(3, 12.289109945297241),(4, 12.300051927566528),(5, 12.322132110595703),(6, 12.058021783828735),(7, 13.218597173690796),(8, 11.991199016571045),(9, 12.178853034973145),
当monoproc:
for n in range(nombre_de_cycles):
debut = time.time()
paris.reveil()
duree = time.time() - debut
print((n, duree), end=",")
给
(0, 0.19302606582641602),(1, 0.030661821365356445),(2, 0.28160881996154785),(3, 0.04853320121765137),(4, 0.20609474182128906),(5, 0.04185295104980469),(6, 0.20528626441955566),(7, 0.040557146072387695),(8, 0.19860100746154785),(9, 0.11386394500732422),
以下是功能:
Class Ville:
timestamp = 0
def __init__(self, nb_de_cyclistes, Prestataire):
self.timestamp =0
def reveil(self):
self.timestamp += 1
list(map(lambda cycliste :cycliste.avancer(self.timestamp), self.cyclistes))
def faire_avancer(cycliste):
cycliste.avancer(Ville.timestamp)
def reveil_multiproc(self, n_jobs=1):
import multiprocessing
self.timestamp += 1
Ville.timestamp = self.timestamp
pool = multiprocessing.Pool(n_jobs)
pool.map(Ville.faire_avancer, self.cyclistes)
我做错了什么?
多处理不是一刀切的解决方案。您的解决方案只需要很少的工作就会产生很大的开销。
您有以下开销:创建2个工作进程,将self.cylistes
拆分为块,使用pickle
序列化,并使用IPC将其发送到子进程。所有这些只是简单地调用cycliste.avancer()
,这似乎做了很少的工作。
拥有数十万件物品的大量清单是微不足道的,当我们无法看到你在avancer()
做多少工作时,没有任何意义。您在这里拥有的项目实际上很可能会减慢多处理方法的速度,因为您不太可能实现pickle
性能的优化。
在进行过早优化之前,您需要学习如何使用Python的分析工具(例如:cProfile,line_profiler)。
当您有长时间运行的CPU密集型任务时,请使用multiprocessing
,这些任务不会花费大部分时间等待IO。如果每次调用avancer()
需要30秒才能运行,那么你会看到multiprocessing
在没有它的情况下表现更好。