You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中高效并行执行函数生成列表?优化现有耗时代码

优化并行执行效率的方案

你的代码耗时过长的核心问题是重复调用了slicecatch(i)——每个i在budx和budy中都被处理了一次,相当于做了两倍的IO/数据加载工作,同时两次启动Parallel也会带来额外的进程启动开销。以下是针对性的优化方案:

核心优化思路

  • 合并两个计算逻辑到单个函数中,每个i只调用一次slicecatch(i),同时计算两个所需的比值
  • 只启动一次并行任务,避免多次初始化并行池的开销
  • 统一异常处理逻辑,减少冗余代码

优化后的代码

import time
import random
from joblib import Parallel, delayed

catchments = 50   #define number of catchments to plot here
randomlist = random.sample(range(2, 2100), catchments)

def compute_bud_values(i):
    try:        
        catch = slicecatch(i)
        prec_mean = catch.Prec.mean().values
        # 一次获取catch后,同时计算两个比值
        budx_val = catch.PETNatVeg.mean().values / prec_mean
        budy_val = catch.TotalET.mean().values / prec_mean
        return (budx_val, budy_val)
    except IndexError as e:
        # 异常时返回两个None,保证结果列表长度一致
        return (None, None)

start_time = time.perf_counter()

# 一次并行执行所有任务,得到包含二元组的结果列表
results = Parallel(n_jobs=-1)(delayed(compute_bud_values)(i) for i in randomlist)

# 将结果拆分到两个列表中
bud_x, bud_y = zip(*results)
# 如果需要列表类型(zip返回元组),可以转换:
# bud_x = list(bud_x)
# bud_y = list(bud_y)

finish_time = time.perf_counter()

额外优化建议

  • 如果slicecatch(i)是IO密集型操作(比如读取文件),可以加入缓存机制,用functools.lru_cache缓存slicecatch的结果(注意i要是可哈希类型),进一步避免重复计算:
    from functools import lru_cache
    
    @lru_cache(maxsize=None)
    def slicecatch(i):
        # 原slicecatch的实现代码
        ...
    
  • 若计算是CPU密集型,joblib默认的多进程模式没问题;如果是IO密集型,可尝试改用多线程模式(backend="threading"),减少进程切换开销:
    results = Parallel(n_jobs=-1, backend="threading")(delayed(compute_bud_values)(i) for i in randomlist)
    

内容的提问来源于stack exchange,提问作者Zeeshan Asghar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 23:10:25