请不要把 Flask 和 FastAPI 放到一起比较

2021-05-04 11:37:37 +08:00
 greyli

https://greyli.com/flask-fastapi/

TLDR: FastAPI 是基于 Web 框架 Starlette 添加了 Web API 功能支持的(框架之上的)框架,而 Flask 是和 Starlette 同类的通用 Web 框架,两者不应该放到一起比较。

文中观点或有偏颇,欢迎指正和补充。

8294 次点击
所在节点    Python
35 条回复
Kobayashi
2021-05-04 14:25:43 +08:00
@abersheeran 这个 benchmark 没任何意义。视图函数是空的,匹配到直接返回空字符串,和实际完全脱钩,最起码得带一次数据库请求吧。

还是 tech empower benchmark 吧,测试指标更多,从不同方面比较。tech empower 里的 plaintext 指标应该对应你发的这个框架比较。
https://www.techempower.com/benchmarks/
https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview
Kobayashi
2021-05-04 14:30:16 +08:00
@wdhwg001 Quart 倒是完全兼容了 Flask,有足够的钩子,还引入了上下文。不过好像性能与其他 Python 异步框架比还是差了点。
不过 FastAPI 只能算是一个个人项目,项目维护值得怀疑。PR 有 280+没有处理……
Richard14
2021-05-04 14:45:33 +08:00
@wdhwg001 我觉得主要原因还是对程序员心智负担的降低,在同样场景下,线程访问共享资源是需要锁的,而 python 的锁偏偏很重,难以优化,threadlocal 同理,这两点在 aio 中被有效解决。
abersheeran
2021-05-04 14:51:36 +08:00
@Kobayashi 微框架都是用社区的 ORM,这玩意我觉得加不加都行。如果是和 Django 比,那确实要带上数据库查询才比较公平。

@LeeReamond 我只觉得总有人把线程模型和协程模型的框架放一起比较性能,很有倾向性。不公正。
而且最近 pydantic 作者拉上 fastapi 一起裹挟群众强行把一个 pep 退回去了,总感觉有些飘了。
Kobayashi
2021-05-04 15:26:53 +08:00
@abersheeran 问题不是我们没有比较哪个 ORM 更快,而是没有顾忌数据库请求甚至其他因素对于整个请求的影响。

尽管 HTTP 请求和数据库查询都可以异步,但引入对数据库查询的考虑,势必也会对最终数据有影响。我从公司门口走到工位需要 10 秒,你花了 20 秒,但考虑到我们两个坐电梯上楼的事件,也不能说其中一人比另一人快 2 倍吧。

Andrew Godwin 在 19 年 AU Pycon 上也提出过类似的说法,

> most of the program i write tend to spend at least 2/3 of time waiting for database and they can't do anything.

(当然这是本地、或集群内部的情况,也没人想不开跨区域使用数据库吧)

从测试代码与实际请求的贴合程度考虑,只考虑数据库请求可能也不够,这也是大多数人觉得 benchmark 没有意义的主要原因。但数据库请求的确是大多数接口最常做的事情。

而我们这里只是一个字符串空响应的 benchmark,实在是过于简陋、与实际偏离太远了。
greyli
2021-05-04 15:34:25 +08:00
@Kobayashi 性能不清楚,补充一点关于 Quart 的额外信息:从 Flask 2.0 开始,Quart 会是官方推荐的 Async Flask 替代选项。Flask 2.0 支持的 async/await 是一个折中方案(基于 asgiref 做的 WSGI->ASGI 转换),如果想要完全基于 ASGI 的异步实现那么可以选择 Quart (和 Flask API 基本保持一致)。前段时间也在讨论把 Quart 加入到 Pallets 组织作为官方项目维护(暂时还没有定具体时间,可以先看作小道消息)。
abersheeran
2021-05-04 15:37:56 +08:00
@Kobayashi 我倒是觉得做这个 benchmark 就够了。能体现框架本身的代码运行速度如何,屏蔽掉其他的因素。

实际业务里干扰很多的。比如来个 N+1 查询,哪怕这框架优化到特定平台指令集上级别都没有什么用。再比如说 asyncio 的框架其实在业务里都有一个缺点,就是大部分程序员都没办判断出自己是不是在异步框架里跑了同步耗时操作,所以往往上了异步反而没有同步的框架快。

benchmark 说到底就是个能用于营销的本钱。“最快的框架”,多唬人啊。
abersheeran
2021-05-04 15:40:58 +08:00
@greyli Flask2.0 的异步支持是用第三方中间件把 WSGI 转 ASGI ???
greyli
2021-05-04 15:58:16 +08:00
@abersheeran 目前是这样实现的( https://github.com/pallets/flask/pull/3412 ),当然这只是第一步,完全的 ASGI 支持会在 Werkzeug 实现( https://github.com/pallets/werkzeug/issues/1322 ),不过不确定哪天能实现。
abersheeran
2021-05-04 16:05:41 +08:00
@greyli 看了看这个 issue 的讨论,感觉我好像抢在 werkzeug 之前把支持双协议的 framework/toolkit 做完了 https://github.com/abersheeran/baize 。hhh 有时候个人开发的好处就是有想法可以直接干完,社区就需要讨论讨论。
greyli
2021-05-04 16:12:10 +08:00
@abersheeran 哈哈,是的。我上个月提议加 app.get 、app.route 、app.delete 这些装饰器一开始是被拒绝的,后来另一个成员创建了一个 PR 经过二次讨论后才最终合并(被拒绝后我就把正在开发的 APIFlask 从扩展改成了继承 Flask 基类的框架,然后加了这些装饰器)。
greyli
2021-05-04 16:14:48 +08:00
app.route -> app.post
abersheeran
2021-05-04 16:40:19 +08:00
@greyli hhh 被拒之后自己重开,我老这么干。
johnsona
2021-05-04 19:08:19 +08:00
@mekingname 好家伙 v 站卧虎藏龙 居然把文章作者炸出来
encro
2021-05-04 23:03:44 +08:00
首先感谢作者对开源的贡献,
然而比较无法回避,
避免被比较的唯一办法就是胜出。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/774831

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX