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

Asyncio与Concurrent Futures性能差异显著?Python异步优化问题咨询

异步优化Python代码的性能差异问题

我尝试通过异步方式优化Python代码,分别使用了asyncio和concurrent.futures库,测试结果差异明显:

  • 无asyncio的同步版本耗时约22秒
  • 使用asyncio的版本耗时约20秒
  • 使用concurrent.futures的版本仅耗时约3秒

以下是我的代码:

asyncio版本代码

async def get_rds_instances(session, region, engine_types):
    report_rds = []
    mandatory_tags = {'Use-Case'}

    client = session.client('rds', region_name=region)
        try:
            await asyncio.sleep(1)
            response = client.describe_db_instances()
            rds_report.append(response)
        except (ClientError, Exception) as e:
            print(e)
    return reportd_rds

async def main():
... some arguments definition
    session = get_rds_session(profile_name)
    regions = session.get_available_regions('rds')
    try:
        reports = await asyncio.gather(*[get_rds_instances(session=session, region=region, engine_types=engine_types) for region in regions])
    except Exception as e:
        print(f"An error occurred: {str(e)}")
    
    ... process report

if __name__ == "__main__":
    asyncio.run(main())

concurrent.futures版本代码

def get_rds_instances(session, region, engine_types):
    report_rds = []
    mandatory_tags = {'Use-Case'}

    client = session.client('rds', region_name=region)
        try:
            response = client.describe_db_instances()
            rds_report.append(response)
        except (ClientError, Exception) as e:
            print(e)
    return reportd_rds


def main():
... some arguments definition
    session = get_rds_session(profile_name)
    regions = session.get_available_regions('rds')
    try:
        args = ((session, region, engine_types) for region in regions)
        with concurrent.futures.ThreadPoolExecutor() as executor:
        reports = executor.map(lambda p: get_rds_instances(*p), args)
    except Exception as e:
        print(f"An error occurred: {str(e)}")

    ... process report

if __name__ == "__main__":
    main()

请问这种性能差异是否正常?我在使用asyncio时是否存在疏漏或错误?

编辑:描述RDS实例(对应原接口describe_db_instances)


问题解答

这种性能差异完全正常,你的asyncio版本没有真正实现异步IO,核心问题有两个:

  1. 使用了boto3同步客户端:client.describe_db_instances()是阻塞式的同步调用,它会占用asyncio的事件循环线程,导致其他任务无法执行——直到这个同步调用完成,事件循环才能继续处理下一个任务。这就相当于把同步代码套了一层async的壳,根本没发挥异步的优势,所以耗时和同步版本几乎一致。

  2. 代码中的低级错误:你的asyncio代码里存在变量名拼写错误(比如report_rds和rds_report、reportd_rds不统一),不过这不会影响性能,只是会导致运行报错。

而concurrent.futures的ThreadPoolExecutor版本能快速运行的原因是:boto3的同步调用属于IO密集型操作,在等待AWS返回响应时,Python的GIL会被释放,线程池可以同时处理多个请求,实现并行的IO等待,所以耗时大幅降低。

如果想让asyncio版本达到类似的性能,有两种解决方案:

  • 使用aioboto3(boto3的异步版本),它提供了真正的异步客户端,所有API调用都是async/await风格的非阻塞操作。
  • 把boto3的同步调用包装到asyncio的线程池里执行,比如用await asyncio.to_thread(client.describe_db_instances),这样能让事件循环在等待IO时处理其他任务。

内容的提问来源于stack exchange,提问作者Umut TEKİN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:07:08