Python中Ray并行化高效使用方法?为何比Joblib慢?
问题:Ray运行效率远低于Joblib的原因分析
我正在学习使用Ray API,并将其与Joblib的代码进行对比(我的设备配备16核CPU)。但测试后发现Ray运行效率远低于Joblib,想请教:我的代码是否存在问题?若代码无误,Ray为何会慢这么多?
代码示例
import ray from joblib import Parallel, delayed num_cpus = 16 @ray.remote(num_cpus=num_cpus) def square(x): return x * x def square2(x): return x * x
Ray运行结果
%%time # Launch parallel square tasks. futures = [square.remote(x=i) for i in range(1000)] # Retrieve results. print(len(ray.get(futures))) # CPU times: user 310 ms, sys: 79.7 ms, total: 390 ms # Wall time: 612 ms
Joblib运行结果
%%time futures = Parallel(n_jobs=num_cpus)(delayed(square2)(x=i) for i in range(1000)) print(len(futures)) # CPU times: user 92.5 ms, sys: 21.4 ms, total: 114 ms # Wall time: 106 ms
问题分析与解答
1. 代码存在关键错误
你的Ray代码犯了一个核心配置错误:@ray.remote(num_cpus=num_cpus) 给每个square任务分配了16核CPU。这意味着你的16核设备每次只能运行一个任务——单个任务就占满了所有计算资源,1000个任务只能串行执行,再加上Ray本身的调度开销,速度自然远不如Joblib。
而Joblib的n_jobs=num_cpus是指用16核并行处理任务,1000个小任务可以被拆分到16核上同时执行,资源利用效率完全不同。
修正Ray代码的方法很简单,将每个任务的CPU分配改为1(或不指定,默认值即为1):
@ray.remote(num_cpus=1) # 或直接写@ray.remote def square(x): return x * x
2. 即使代码修正,Ray仍可能在小任务场景慢于Joblib
Ray的定位是分布式计算框架,支持跨机器、跨节点的大规模任务调度,它的调度系统、进程间通信机制都带有一定的固定开销。对于像square(x)这种极轻量的小任务,Ray的调度开销会占总运行时间的很大比例。
而Joblib是针对单机轻量并行任务优化的工具,它的调度和通信开销远低于Ray,在处理大量小任务的场景下,单机性能更有优势。
Ray的优势体现在:
- 处理需要跨节点的分布式任务
- 任务本身计算量较大,调度开销可忽略
- 需要使用Ray的高级特性(如状态管理、Actor模型、动态任务图等)
内容的提问来源于stack exchange,提问作者O.rka
相关产品推荐
相关产品推荐

