使用joblib实现并行化未提升性能,求问题排查
并行化性能不升反降的原因及解决办法
你的测试代码出现性能暴跌的核心原因是任务粒度太细,并行计算带来的额外开销完全抵消甚至超过了多进程的计算收益。
具体原因
- 单个任务计算量极小:
sqrt(i**2)是非常简单的运算,单次执行耗时可以忽略,但用delayed包装每个任务、在进程间传递参数和结果的开销,比计算本身大几个数量级。 - 串行版本效率极高:Python的列表推导式是底层C实现的循环,执行效率远高于Python层面的任务分发+多进程调度流程。
改进方案:增大任务粒度
把大量小任务打包成少数大任务,减少任务分发、进程通信的次数,让并行计算的优势显现出来。
修改后的示例代码:
from math import sqrt from joblib import Parallel, delayed import time i_range = 1000000 chunk_size = 10000 # 每块处理10000个元素,可根据实际情况调整 def process_chunk(chunk): # 单块内用高效的列表推导式批量计算 return [sqrt(i**2) for i in chunk] # 将数据拆分为多个块 chunks = [range(i, min(i+chunk_size, i_range)) for i in range(0, i_range, chunk_size)] # 串行基准测试 start = time.time() [sqrt(i ** 2) for i in range(i_range)] end = time.time() print("串行耗时 = %s" % (end - start)) # 并行测试 start = time.time() results = Parallel(n_jobs=2)(delayed(process_chunk)(chunk) for chunk in chunks) # 合并各块结果 combined_results = [item for sublist in results for item in sublist] end = time.time() print("并行耗时 = %s" % (end - start))
效果说明
调整后任务数量从100万缩减到100个,并行的调度和通信开销被大幅分摊,当计算量足够大时,多进程就能体现出性能优势。
内容的提问来源于stack exchange,提问作者user7077259
相关产品推荐
相关产品推荐

