Python循环中用multiprocessing优化:康威生命游戏性能问题
优化康威生命游戏的多进程实现
你的核心问题是在循环内反复创建和销毁进程池——每次with Pool(jobs) as pool都会启动一批新进程,循环结束后又销毁,这个开销在多次迭代下会被放大,直接拖慢整体运行速度。最简洁的优化方案是复用同一个进程池,避免重复初始化进程的开销。
修改后的核心代码
grid: Grid = Grid(grid_size) grid_array: np.ndarray = grid.grid_init(initialization.value) living_cells: set[tuple] = find_living_cells(grid_array) living_cells_subsets = _create_subsets(living_cells, jobs) # 将进程池创建移至循环外部,仅初始化一次 with Pool(jobs) as pool: while grid_array.any(): args = [(grid_array, subset) for subset in living_cells_subsets] # 复用已创建的进程池执行任务 result = pool.starmap(update_positions, args) living_cells = set() prev_living_cells = set() for res in result: living_cells.update(res[0]) prev_living_cells.update(res[1]) grid_array = update_grid(grid_array, living_cells, prev_living_cells) living_cells_subsets = _create_subsets(living_cells, jobs)
关键改动说明
- 复用进程池:把
with Pool(...)放在while循环外层,进程池仅启动一次,所有迭代都复用这批进程,彻底消除了反复创建/销毁进程的开销。 - 简化同步逻辑:
starmap是阻塞式方法,会自动等待所有任务完成后返回结果,不需要手动调用pool.join()。 - 保持原有逻辑不变:除了进程池的位置,其他业务逻辑完全保留,不需要修改
update_positions、update_grid等核心函数。
备选手动管理方式(非with版本)
如果需要更灵活的进程池生命周期控制,可以手动创建和关闭:
pool = Pool(jobs) try: while grid_array.any(): args = [(grid_array, subset) for subset in living_cells_subsets] result = pool.starmap(update_positions, args) # 后续处理逻辑同上 living_cells = set() prev_living_cells = set() for res in result: living_cells.update(res[0]) prev_living_cells.update(res[1]) grid_array = update_grid(grid_array, living_cells, prev_living_cells) living_cells_subsets = _create_subsets(living_cells, jobs) finally: pool.close() pool.join()
额外小优化建议
- 如果
update_positions单任务执行时间较短,可考虑用pool.imap或pool.imap_unordered替代starmap,减少一次性传递所有参数的内存占用。 - 确保
grid_array在传递给子进程时是只读状态(当前代码每次循环生成新数组,天然满足这一点),避免进程间的意外数据冲突。
内容的提问来源于stack exchange,提问作者Raphaellndr
相关产品推荐
相关产品推荐

