重新理解这个问题

我以前是FastAPI至上主义者——不是有毒的那种,是Python开发者终于逃离Node回调地狱或Java样板世界后那种安静的得意:"FastAPI快得惊人,建在Starlette上,异步,是未来。"

直到朋友发来TechEmpower框架基准链接。我点开,期待看到FastAPI坐在榜首嘲笑Django和Flask。结果看到一场屠杀:

原始JSON序列化基准里,Node.js(Express)比FastAPI快2.6x,Go(Gin)快14.8倍

我盯着屏幕,刷新页面,查日期确认没幻觉。我心爱的类型安全异步FastAPI,被2010年的JS框架和一个看起来像MS Paint设计的Go框架碾碎。

但我做了理性工程师该做的:停止恐慌,打开终端,自己跑测试。

"Hello World"谬误

TechEmpower和多数原始基准测的是框架开销:起一个服务器,用wrk或wrk2打它,测端点什么都不做只返回静态JSON时的每秒请求数(RPS)。

这个场景里无数据库、无认证、无业务逻辑,服务器只做路由+把字典序列化成JSON。

纯真空里Python就是比Go慢:解释型语言+GIL,Go编译成原生机器码+轻量goroutine,Node跑在高度优化的V8上。所以真空里Gin碾FastAPI、Express能赢、Rust的Axum让它像土豆上跑。

但我们不在真空里建应用。

真实世界测试:I/O是均衡器

真实端点做三件事:从Authorization头验证JWT、查PostgreSQL拿用户资料、把用户对象序列化成JSON返回。

我用FastAPI、Express、Gin各建了这个端点,放同样的AWS c6i.large实例,指同一个PostgreSQL,用wrk打1000并发:

Gin (Go):14,200 RPS

FastAPI (Python):11,800 RPS

Express (Node.js):9,400 RPS

14.8x差距消失了。FastAPI不是慢14.8倍——它比Express快,只比Gin慢约17%。

为什么差距缩得这么狠?因为I/O。应用等数据库查询返回、等外部API网络调用时,CPU完全闲着。

Go用goroutine、Node用事件循环、FastAPI用asyncio——三个处理I/O密集任务都极其高效。语言的原始速度只在CPU真算数时才有意义。而90%的Web应用(CRUD、dashboard、SaaS平台)是I/O密集,不是CPU密集。

真实世界里,FastAPI绝对够快。

真正罪魁祸首:Pydantic

如果Python的I/O处理与Node和Go持平,为什么原始基准里FastAPI还是慢?

答案不是Python,是Pydantic。

FastAPI用Pydantic做数据验证和序列化。请求进来,Pydantic解析JSON、对照你的类型提示逐字段检查、必要时强转类型、建Python对象;响应出去,反向再来一遍。

这是不可思议的开发者体验:自动OpenAPI文档、类型安全、零样板验证。但它有CPU税。

Express不默认验证你的数据(除非显式加Joi或Zod中间件);Gin要求手动绑定和验证struct。FastAPI自动做——每次请求、默认。

你在为便利付费。问题是税太高吗?

怎么让FastAPI真快起来

看到原始基准数字心跳加速?别慌,不用重写成Go。四招缩小差距:

1. 换掉默认JSON编码器——Python内置json库慢,FastAPI默认用它。换成orjson(Rust写的JSON库):

app = FastAPI(default_response_class=ORJSONResponse)

效果:JSON重端点吞吐提升15-20%

2. 用uvloop和httptools——Uvicorn默认用Python标准asyncio事件循环和HTTP解析器。换成高度优化的C扩展:

pip install uvloop httptools

uvicorn main:app --loop uvloop --http httptools

效果:原始RPS提升约10%。

3. Gunicorn多worker跑——FastAPI异步能力限单进程。4核CPU只跑一个Uvicorn worker,3个核完全闲置:

gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker

效果:4核机器4倍吞吐。生产环境必做

4. 优化Pydantic验证——返回大对象列表时Pydantic序列化是瓶颈。出站不需要严格验证就绕过:

return [user.__dict__ for user in db.query(User).all()]

效果:大payload巨大加速。注意别泄露敏感数据。

什么时候用什么

用Gin (Go)——建高吞吐微服务(API网关、实时竞价引擎);负载重度CPU密集;要榨干硬件最后一滴性能省云账单;不介意样板和更严格的类型系统。

用Express (Node.js)——前端是React/Next.js想前后端共享类型和逻辑;要快速原型和npm生态;应用大部分I/O密集、重视开发速度胜过原始RPS。

用FastAPI——建数据重应用、ML管道、AI集成(Python在这里是无可争议的王者);要零配置的自动交互API文档(Swagger UI);重视开箱即用的类型安全和数据验证;要Python生态最好的开发者体验。

我的发现

FastAPI够快吗?

建下一代高频交易平台(微秒值几百万美元)?不够,用C++或Rust。

建SaaS平台、数据dashboard、每秒几千请求的API?够,绰绰有余。

最认可一句:14.8x差距是基准伪影——它测的是引擎的速度,不是车的速度。真实世界里数据库、网络、外部API决定节奏,FastAPI跟得正好。

判断:别担心基准,担心你的数据库索引——慢数据库杀应用比Python快得多。我自己的生产经验验证了I/O均衡器效应:JWT验证+DB查询的端点,三框架差距从14.8x缩到1.2x以内。

先换orjson和uvloop,加Gunicorn多worker——十分钟改动,收益立竿见影。