ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FastAPI 基准测试真相解读:Uvicorn、Starlette 与 FastAPI 的分层性能架构

FastAPI 基准测试真相解读:Uvicorn、Starlette 与 FastAPI 的分层性能架构 FastAPI 基准测试真相解读Uvicorn、Starlette 与 FastAPI 的分层性能架构【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapiTechEmpower 的独立基准测试曾多次将运行在 Uvicorn 之上的 FastAPI 应用列为「Python 生态中最快的 Web 框架之一」但它始终排在使用其内部的 Starlette 与 Uvicorn 之后——这并非巧合而是一个由分层架构决定的结构性事实。本篇指南以官方 Benchmarks 文档为核心对应葡萄牙语版本 docs/pt/docs/benchmarks.md逐层拆解 Uvicorn → Starlette → FastAPI 的继承关系如何影响性能表现并给出公平、科学的对比方法论与跨语言对照对象帮助你正确阅读任何第三方基准报告。官方基准结果与正确打开方式官方文档开篇即指出TechEmpower 等独立基准测试显示FastAPI 应用运行于 Uvicorn 之上是 Python 可用的最快框架之一仅低于被 FastAPI 内部使用的 Starlette 与 Uvicorn 本身。但紧接着文档给出一个关键提醒——当人们查看基准测试与框架对比时应当始终牢记以下几点各类基准测试中不同「类型」的工具常常被当作等价物并列比较最常见的误区是把 Uvicorn、Starlette、FastAPI 三个不同层次的东西放在一起排队打分同时与众多其他工具混排工具解决的问题越简单其测得的性能就越好而绝大多数基准测试并不会去衡量工具所提供的「额外特性」因此看到排名时不能只看数字必须搞清楚被测对象到底承担了多少职责。这里的「职责分层」正是理解一切的关键官方文档给出的层级结构如下Uvicorn一个 ASGI 服务器Starlette使用 Uvicorn一个 Web 微框架FastAPI使用 Starlette一个面向 API 构建、内置数据校验等多项额外能力的 API 微框架分层架构的源码证据这一层级关系不仅是文档表述在当前仓库的源码与依赖配置中处处可证。第一层证据类继承关系。在 fastapi/applications.py 中FastAPI 的核心应用类直接继承自 Starletteclass FastAPI(Starlette):继承意味着 FastAPI 应用在处理请求时必然叠加在 Starlette 之上执行因此在架构上不可能快过 Starlette 自身——文档中「Starlette 用了 Uvicorn 就不可能比 Uvicorn 快FastAPI 用了 Starlette 同理」的论断正源于此。第二层证据依赖声明。pyproject.toml 的运行时依赖中明确写入starlette0.46.0与pydantic2.9.0而 fastapi/applications.py 从starlette.applications、starlette.middleware、starlette.requests、starlette.responses等模块大量导入并复用组件FastAPI 并不是「重写」了 Web 框架而是在 Starlette 之上扩展 API 语义路径操作、依赖注入、数据模型校验等。同样Uvicorn 作为可选依赖出现在 pyproject.toml 的uvicorn[standard] 0.12.0中对应文档所描述的运行方式。逐层解读每层快在哪里、慢在何处官方文档对三层分别给出了精确的定位与性能含义下面逐层还原并补充解读。Uvicorn 层性能天花板但不能直接写应用Uvicorn 会拥有最好的性能因为它除服务器本身外几乎没有多余代码但你无法直接在 Uvicorn 上编写应用程序——那意味着你的代码必须自行实现 Starlette或 FastAPI提供的几乎所有东西。如果真的这样做最终应用的总开销与使用一个帮你把业务代码和 bug 都最小化的框架实际上没有差别换言之裸用 Uvicorn 节省的开销会被你在应用层手工重写路由、生命周期、请求解析等基础设施的成本完全抵消。公平对比对象如果你要对比 Uvicorn应该与 Daphne、Hypercorn、uWSGI 等**应用服务器Application Servers**比较而不是与 Web 框架比较。Starlette 层在 Uvicorn 之上的微框架在 Uvicorn 之后Starlette 拥有次优的性能。它实际上运行于 Uvicorn 之上必须执行更多代码因此只会比 Uvicorn 慢但它提供了构建简单 Web 应用的成套工具例如基于路径的路由等注意区分角色Starlette 是「通用 Web 微框架」并不内置数据校验与序列化。公平对比对象与 Starlette 比较应当使用 Sanic、Flask、Django 等Web 框架或微框架。FastAPI 层在 Starlette 之上叠加 API 必需能力如同 Starlette 依赖 Uvicorn、无法比 Uvicorn 更快FastAPI 依赖 Starlette因此不可能比 Starlette 快FastAPI 提供的是构建 API 时几乎总会用到的能力——数据校验与序列化使用这些能力的同时你会免费获得自动交互式文档。更重要的是自动文档不会给运行时应用增加任何开销因为它是在应用启动时生成的若不用 FastAPI 而直接用 Starlette或其他工具如 Sanic、Flask、Responder 等你仍需要自己实现全部数据校验与序列化。在很多项目中这部分恰恰是应用里体量最大的代码你的最终应用依旧会背负与 FastAPI 相同的开销而且这些代码还可能引入更多 bug。自动文档「零运行时开销」的源码印证文档中关于「自动文档不会增加运行开销、仅在启动时生成」的论断可以在 fastapi/applications.py 的openapi()方法中得到直接印证OpenAPI schema 在首次被请求时生成并缓存到self.openapi_schema属性中后续调用直接返回缓存结果只有当路由集合发生变化routes_version改变时才会重新生成routes_version self.router._get_routes_version() if not self.openapi_schema or self._openapi_routes_version ! routes_version: self.openapi_schema get_openapi(...) self._openapi_routes_version routes_version return self.openapi_schema也就是说日常请求处理路径完全不经过 schema 构建逻辑文档生成的成本被隔离在「首次访问/openapi.json或应用启动」的一次性步骤中这从实现层面支持了文档「零运行开销」的结论。仓库自带的基准测试项目如何自我测量为了印证对自身分层结构的理解仓库还内置了一套基准测试用例位于 tests/benchmarks 目录下可作为研究 FastAPI 性能特性的第一手材料。常规路径基准测试tests/benchmarks/test_general_performance.py 覆盖了非常细致的对比矩阵按如下维度排列组合同步sync与异步async路径函数返回普通 dict 与返回 Pydantic 模型是否声明response_model即是否走响应校验与序列化路径是否带有依赖注入嵌套Depends依赖小负载与大负载该文件中定义了一个包含 300 个条目、每条约 25 个字段的LARGE_PAYLOAD。例如它同时测了/sync/dict-no-response-model与/sync/dict-with-response-model两种端点用于量化response_model校验对吞吐的影响app.get(/sync/dict-no-response-model) def sync_dict_no_response_model(): return {name: foo, value: 123} app.get(/sync/dict-with-response-model, response_modelItemOut) def sync_dict_with_response_model( dep: Annotated[int, Depends(dep_b)], ): return {name: foo, value: 123, dep: dep}这与官方 benchmarks 文档的核心思想高度一致框架层的额外能力校验、序列化、依赖解析是有真实开销的测量时必须把这些功能差异显式纳入考量而不是把「带完整校验的 API 框架」与「裸服务器」混为一谈。OpenAPI 生成开销基准tests/benchmarks/test_openapi.py 与 tests/benchmarks/utils.py 则针对文档提到的「自动文档在启动时生成」进行专项测量utils.py会构造一个包含 100 层链式依赖、20 条动态路由的应用反复调用app.openapi()来测量复杂依赖图下的 schema 生成成本。从源码结构看这些测试默认处于跳过状态只有在sys.argv中检测到--codspeed参数时才真正执行见 test_general_performance.py说明它们面向 CodSpeed 这类持续性能基准平台而非常规单元测试流程。正确解读基准数字的方法论综合官方文档的论述与仓库实现可以提炼出阅读任何框架基准测试的完整方法论先确认被测对象的层级是应用服务器Uvicorn/Daphne/Hypercorn/uWSGI、Web 微框架Starlette/Flask/Sanic/Django还是带内置校验、序列化与文档的 API 框架FastAPI/Flask-apispec/NestJS/Molten只与同层工具比较对比 FastAPI 时应当选择同样内置自动数据校验、序列化与文档能力的 Web 应用框架或工具集如 Flask-apispec、NestJS、Molten 等而不是与不带这些能力的框架比较识别未计入的特性多数基准不测试工具提供的额外特性解决问题的复杂度越低工具的得分越高。一个「零校验裸返回」的基准分数不能代表真实业务 API 的性能把「自研开销」算进去如果用更低层的方案你得在自己代码里补上路由、校验、序列化等全部能力——这些代码本身也会产生运行时开销与 bug 维护成本。从总拥有成本看框架层能力校验与序列化往往才是应用里最大的代码块结论应落在工程收益上文档最终给出的判断是——使用 FastAPI 能节省开发时间、减少 bug、压缩代码量而最终应用的性能很可能与不用它时持平甚至更好因为你省去了自己实现这些功能时的开销与错误。小结FastAPI 在基准中的排名从来不是「魔法」而是分层架构的必然结果它构建于 Starlette 之上、而 Starlette 又运行于 Uvicorn 之上因此单体性能必然不可能超过下层组件但 FastAPI 提供的恰恰是构建真实 API 时必不可少的校验、序列化与零运行时开销的自动文档。读懂 Benchmarks 文档等于掌握了一套判断工具对比是否公平的通用框架——无论是评估 FastAPI还是评估任何宣称「更快」的新框架先问一句它解决的问题和我需要解决的问题真的是同一件事吗想要进一步研究可在本仓库中依次阅读官方基准说明英文版、依赖与版本声明、FastAPI 应用类继承与 OpenAPI 缓存实现、以及仓库自带的 常规路径基准测试 与 OpenAPI 基准测试。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表