同步请求和异步请求的性能测试代码

性能测试说明

测试内容:连续发起20次HTTP请求,分别测试:

  1. 同步串行 requests
  2. 多线程并发 requests
  3. 协程异步 aiohttp

统一目标地址,控制超时,统计总耗时,直观对比差距。

完整测试代码

python 复制代码
import time
import threading
import requests
import asyncio
import aiohttp

# 配置
TEST_URL = "https://httpbin.org/get"
REQUEST_COUNT = 20
TIMEOUT = 5


# ---------------------- 1. 同步串行请求 ----------------------
def sync_request():
    start = time.time()
    session = requests.Session()
    for _ in range(REQUEST_COUNT):
        try:
            session.get(TEST_URL, timeout=TIMEOUT)
        except Exception:
            pass
    cost = round(time.time() - start, 2)
    print(f"【同步串行】{REQUEST_COUNT}次请求,总耗时:{cost} s")


# ---------------------- 2. 多线程 requests 并发 ----------------------
def thread_fetch():
    try:
        requests.get(TEST_URL, timeout=TIMEOUT)
    except Exception:
        pass

def thread_request():
    start = time.time()
    tasks = []
    for _ in range(REQUEST_COUNT):
        t = threading.Thread(target=thread_fetch)
        tasks.append(t)
        t.start()
    for t in tasks:
        t.join()
    cost = round(time.time() - start, 2)
    print(f"【多线程并发】{REQUEST_COUNT}次请求,总耗时:{cost} s")


# ---------------------- 3. 异步 aiohttp 并发 ----------------------
async def async_fetch(session):
    try:
        await session.get(TEST_URL, timeout=aiohttp.ClientTimeout(total=TIMEOUT))
    except Exception:
        pass

async def async_main():
    async with aiohttp.ClientSession() as session:
        tasks = [async_fetch(session) for _ in range(REQUEST_COUNT)]
        await asyncio.gather(*tasks)

def async_request():
    start = time.time()
    asyncio.run(async_main())
    cost = round(time.time() - start, 2)
    print(f"【异步协程】{REQUEST_COUNT}次请求,总耗时:{cost} s")


if __name__ == "__main__":
    sync_request()
    thread_request()
    async_request()

预期运行结果参考

复制代码
【同步串行】20次请求,总耗时:6.85 s
【多线程并发】20次请求,总耗时:0.72 s
【异步协程】20次请求,总耗时:0.65 s

补充版本:限制并发数量(更贴近真实业务)

真实项目不会无限并发,我们加上并发上限,对比效果更真实:

python 复制代码
import time
import asyncio
import aiohttp

TEST_URL = "https://httpbin.org/get"
REQUEST_COUNT = 20
MAX_CONCURRENT = 5  # 限制最大并发量

async def limited_fetch(session, sem):
    async with sem:
        try:
            await session.get(TEST_URL, timeout=aiohttp.ClientTimeout(total=5))
        except Exception:
            pass

async def main():
    sem = asyncio.Semaphore(MAX_CONCURRENT)
    async with aiohttp.ClientSession() as session:
        tasks = [limited_fetch(session, sem) for _ in range(REQUEST_COUNT)]
        await asyncio.gather(*tasks)

if __name__ == "__main__":
    s = time.time()
    asyncio.run(main())
    print(f"限制{MAX_CONCURRENT}并发,总耗时:{round(time.time()-s,2)}s")

总结对比

  1. 同步串行:总时间 ≈ 单次耗时 × 请求总数,最慢;
  2. 多线程:利用多线程等待IO,速度大幅提升,但是线程创建有开销;
  3. 异步协程:轻量级调度,无线程开销,连接池复用TCP,同等并发下速度略优于多线程,内存占用更低。

需要我把这段测试代码整理成博客正文版本吗?