如何使用2个CPU核心并行化for循环以加速Jupyter中的API数据拉取任务
普通for循环(HTTP请求场景)双核心提速方案
你的任务属于IO密集型任务,90%以上的耗时是在等待HTTP请求响应,无论是用多进程还是多线程都可以实现大幅提速,以下给出符合你要求的调用2个CPU核心的多进程实现方案,同时也给出更适配IO场景的多线程方案供选择。
方案1:指定2核心的多进程实现(完全匹配你的需求)
你已经导入了multiprocessing库,无需额外安装依赖,只需要先提取所有待请求的URL列表,替换原有for循环即可。
核心修改代码:
# 先提取所有需要请求的url列表,和原循环顺序完全一致 url_list = [subhalos_z1['results'][i]['url'] for i in range(len_sub)] tstart = time.time() # 初始化2进程的进程池,绑定2个CPU核心 if __name__ == '__main__': with multiprocessing.Pool(processes=2) as pool: sub_z1 = [] # 用imap迭代保留进度打印功能,顺序和原循环完全一致 for idx, res in enumerate(pool.imap(get, url_list)): sub_z1.append(res) print(idx) print("Elapsed Time: {:.2f}s".format(time.time() - tstart))
注意事项:
如果在Jupyter中运行多进程代码无响应,可在导入multiprocessing后添加一行multiprocessing.set_start_method('spawn')解决兼容问题。
方案2:更适配IO场景的多线程实现(开销更小、提速效果更好)
IO密集型任务不需要严格绑定CPU核心数,用多线程的进程间通信开销更低,提速效果反而比多进程更好,你也可以选择这个方案:
核心修改代码:
from concurrent.futures import ThreadPoolExecutor # 先提取所有需要请求的url列表 url_list = [subhalos_z1['results'][i]['url'] for i in range(len_sub)] tstart = time.time() # 线程数可以根据API限流情况调整,2~10都可,IO密集型场景线程数不需要和核心数绑定 with ThreadPoolExecutor(max_workers=2) as executor: sub_z1 = [] for idx, res in enumerate(executor.map(get, url_list)): sub_z1.append(res) print(idx) print("Elapsed Time: {:.2f}s".format(time.time() - tstart))
额外注意事项
- 你的原代码最后时间计算存在变量名笔误:定义的计时变量是
tstart,打印时写的是start,请修正避免时间计算错误 - 注意对应API的请求频率限制,并发数不要过高,避免触发反爬机制被临时封禁IP
- 两种方案都会保留请求结果的顺序,和你原for循环得到的
sub_z1列表顺序完全一致
内容的提问来源于stack exchange,提问作者sydneeod
相关产品推荐
相关产品推荐

