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

为何两段Python多线程调用OpenAI API的代码性能差异巨大?

为什么Python多线程中直接调用requests.post比封装后调用性能差异显著?

测试代码

import requests
from concurrent.futures import ThreadPoolExecutor
import time

def process_payload(payload, url, headers):
    response = requests.post(url, headers=headers, json=payload)
    return response

def parallel_group2(payloads, url, headers):
    with ThreadPoolExecutor() as executor:
        results = executor.map(process_payload,payloads, [url]*len(payloads), [headers]*len(payloads))
    return list(results)

def parallel_group(payloads, url, headers):
    with ThreadPoolExecutor() as executor:
        results = executor.map(requests.post, [url]*len(payloads), [headers]*len(payloads), payloads)
    return list(results)

times = []
# payloads grouped by 15
payloads_grouped = [payloads[i:i+15] for i in range(0, len(payloads), 15)]
print( "shape of payloads_grouped", len(payloads_grouped), " x ", len(payloads_grouped[0]))
for i in range(3):
    start = time.time()
    with ThreadPoolExecutor() as executor:
        # results = executor.map(parallel_group2, payloads_grouped, [url]*len(payloads_grouped), [headers]*len(payloads_grouped))
        results = executor.map(parallel_group, payloads_grouped, [url]*len(payloads_grouped), [headers]*len(payloads_grouped))
    end = time.time()
    times.append(end-start)
    print( "Durations of iterations:", times)
print( "Durations of iterations:", times)
print( "Average time for 150 requests:", sum(times)/len(times))

测试结果

运行parallel_group时(直接调用requests.post)

Durations of iterations: [5.246389389038086, 5.195073127746582, 5.278628587722778]
Average time for 150 requests: 5.2400303681691485

运行parallel_group2时(调用封装后的process_payload)

Durations of iterations: [10.99542498588562, 9.43007493019104, 23.003321170806885]
Average time for 150 requests: 10.142940362294516

注:调用的接口为OpenAI的Chat Completion API(api.openai.com/v1/chat/completions),多次测试结果均保持一致。

原因分析

1. 参数传递错误导致请求逻辑差异(核心原因)

parallel_group函数中,使用executor.map调用requests.post时的参数传递完全错误:

  • requests.post的签名为requests.post(url, data=None, json=None, **kwargs),headers属于关键字参数,必须通过headers=headers的形式传递,不能作为位置参数传入。
  • 当前代码的调用等价于requests.post(url, data=headers, json=payload),把headers当成了请求体的data参数,实际请求并没有携带你需要的授权头(如Authorization)。

这种错误导致parallel_group中的请求被OpenAI API直接拒绝(返回401类错误),无需执行实际的Chat Completion计算,因此处理时间大幅缩短。而parallel_group2中的process_payload函数正确传递了headers,请求会被正常处理,耗时更长。

2. 线程池嵌套的额外开销(次要因素)

即使修正参数传递问题,parallel_group2的嵌套线程池结构也会带来额外性能损耗:

  • 外层线程池的每个线程都会创建并销毁一个内层线程池,增加了线程初始化、调度的重复开销。
  • 过多的线程会提升上下文切换频率,当线程数量超过IO密集型场景的最优值(通常为CPU核心数的2~4倍)时,调度开销会抵消IO等待带来的并发收益,甚至导致性能骤降。

内容的提问来源于stack exchange,提问作者codeur rapide

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:18:11