性能测试说明
测试内容:连续发起20次HTTP请求,分别测试:
- 同步串行 requests
- 多线程并发 requests
- 协程异步 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")
总结对比
- 同步串行:总时间 ≈ 单次耗时 × 请求总数,最慢;
- 多线程:利用多线程等待IO,速度大幅提升,但是线程创建有开销;
- 异步协程:轻量级调度,无线程开销,连接池复用TCP,同等并发下速度略优于多线程,内存占用更低。
需要我把这段测试代码整理成博客正文版本吗?