为什么你的 Python 程序,总是跑得很慢?
很多人第一次写 Python 程序时,都会遇到一个困惑:
电脑配置挺高,CPU 也不差, 可程序一跑起来,慢得像蜗牛。
于是大家开始怀疑:
是不是 Python 不行? 是不是代码写得不够高级?
其实,大多数时候问题只有一个:
你的程序,一直在“排队”。
今天我们用一个非常生活化的例子——厨房做饭,把 Python 里的三个核心概念一次讲透:
看完你就会明白:
为什么有的程序跑 6 秒, 而有的只需要 3 秒。
第一阶段:最原始的程序——水不开,我不动
假设你走进厨房准备做饭。
按照最原始的逻辑,你可能会这样操作:
1️⃣ 先把水壶放炉子上烧水
2️⃣ 站在旁边等 10 分钟
3️⃣ 水开之后再去切菜
4️⃣ 切完菜再开始做饭
问题来了:
在烧水的这 10 分钟里,你什么都没干。
这就是程序里的一个经典问题:
阻塞(Blocking)
程序在等待某件事情完成的时候,整个流程全部停住了。
在 Python 中,这就好比我们按顺序调用函数:

运行结果: 任务 A 跑完花 3 秒,任务 B 跑完花 3 秒,总共耗时 6 秒。效率极低,因为在等待 A 的时候,B 啥也没干。运行逻辑就是:
烧水 → 等 → 烧完 切菜 → 等 → 切完
结果就是:
3 秒 + 3 秒 = 6 秒
效率极低。
但很多初学者写的程序,其实就是这种模式。
第二阶段:多线程(Multi-threading)——主厨与他的“外包”小弟
为了提升效率,饭店引入了“多线程”模式。
在这个模式下,厨房里有一个主厨(操作系统主线程),他还雇了几个厨师 ABCD(子线程)。
- 主厨负责统筹:“厨师 A 你去烧水,厨师 B 你去切菜。”
看起来大家各司其职,速度飞快。但这种模式有三个致命伤:
- 调度开销:主厨(操作系统)得不停地在几个厨师之间切换,告诉 A 停一下,让 B 接着干。这种任务切换本身是需要脑力(CPU 资源)的。
- 资源竞争:如果厨房只有一个烤箱,厨师 A 正在用,厨师 B 也想用。主厨就得出来调解:“A 你先停一下,让 B 先用。”这就涉及到了线程锁(Lock)和 Python 特有的 GIL(全局解释器锁)。
- 内存消耗:如果你开了几百个厨师(线程),厨房就会挤爆,每个厨师都要占用生存空间(内存)。
在Python中代码是这样实现的,利用 Python 的 threading 模块,我们可以让任务“看起来”在并行:
运行结果: A 和 B 几乎同时开始,3 秒左右全部完成。效率提升了,但你要知道,操作系统在背后频繁地切换任务,这对高并发场景来说,压力依然不小。
第三阶段:协程(Coroutine)——一个顶级大厨的自我管理
最后,我们来看现在最火的“协程”。
这次,厨房里依然只有一个大厨。但他是个时间管理大师: 他把水烧上,趁着水没开的间隙,主动跑去切菜;切菜的间隙,又去开一下烤箱。
划重点: 这种切换不是被动(主厨强迫)的,而是大厨自己根据任务状态灵活安排的。
- 没有切换开销:不需要操作系统介入,大厨自己说了算。
- 极省内存:不需要雇佣额外的小弟,一个人干完所有活。
- 适合高并发:一个人可以同时盯着成百上千个“烧水壶”。
这就是:
协程(Coroutine)
程序会在 等待 IO 的时候主动让出执行权。
使用 Python 的 asyncio 模块,也就是现在大名鼎鼎的异步编程方案:
运行结果: 同样是 3 秒完成。虽然也是 3 秒,但它占用的系统资源远小于多线程,是真正的高性能王者。
核心关键字只有两个:async / await
❝多线程是“外包管理”,虽然能干活,但管理费太贵;协程是“自我修养”,不出厨房门,一人抵千军。
总结:我该选哪一个?
通过这个厨房的例子,相信你已经看明白了:
| 模式 | 核心特点 | 适用场景 | 就像... |
|---|
| 阻塞模型 | | | |
| 多线程 | | IO 密集型 | |
| 协程 | | 超高并发 | |
- 多线程: 计算多、等待少,图像处理、视频编码、科学计算、AI模型推理
- 协程:等待很多、计算很少,网络请求、爬虫、API调用、数据库访问、文件读写。
如果你想让你的 Python 代码在处理大量网络请求时“起飞”,那么协程绝对是你必须掌握的核武器。
为什么现在 FastAPI 这么火? 正是因为它原生支持协程,能够以极小的资源处理成千上万的 API 请求。这也是为什么各大模型厂商在提供接口服务时,首选协程方案。
如果你觉得这篇干货对你有帮助,请点个“在看”并转发给你的程序猿朋友!
看完这篇,是不是觉得协程也没那么难?
想看更多关于 Python 实战、异步编程的深度解析吗?
欢迎关注,我们下期再见!
你在写代码时,遇到过最离谱的“阻塞”坑是什么?欢迎在评论区分享吐槽!