📄 一句话概括
编译一次跑 2000 次 vs 每次编译再跑 2000 次,实测多翻译了 1999 次——这就是【重复翻译】的代价。
📝 本节和前面几节的关系
5.1 讲了调用的四步,这一节往上退一层:源码怎么变成能跑的东西。
一、两种方式
编译器:先一次性把源码翻译成机器码,然后执行 N 次。翻译付一次。 解释器:每跑一次就翻译一次。翻译付 N 次。 两者的差别不在语言强弱,在【翻译的钱付几次】。
二、实测
同一段源码跑 2000 次:编译版翻译 1 次、执行 2000 次;不编译版翻译 2000 次、执行 2000 次。 多翻译了 1999 次——执行次数一样,翻译次数差两千倍。 总时间也跟着涨了一大截(具体倍数见输出)——涨的就是那 1999 次翻译。 所以【解释慢】不是慢在执行,是慢在重复翻译。
三、第三条路:混合
编译(C/C++/Go):翻译一次到机器码,快,但换平台要重编。 解释(早期 BASIC):每次翻译,慢,但改一行立刻能跑。 混合(Java/Python):先编译成中间代码,再反复执行它——翻译付一次,跨平台的好处还在。 今天的主流语言基本都走第三条。
四、为什么混合赢了
因为它同时拿到了两头的便宜:翻译只付一次,中间代码不绑 CPU。 代价是中间隔了一层:执行时还要由虚拟机翻译(5.3 讲这个)。 所以现代语言的速度问题,本质是【虚拟机翻译得好不好】。
五、动手 Demo:两种运行方式——编译器与解释器
同一段源码跑 2000 次,一次先编译、一次每次编译。 数一数各翻译了几次、各花了多少时间。
import time
src = "s = 0\nfor i in range(200):\n s += i\n"
N = 2000
code = compile(src, "<src>", "exec")
t0 = time.perf_counter()
for _ in range(N):
exec(code, {}, {}) # 翻译 1 次
t1 = time.perf_counter()
for _ in range(N):
exec(src, {}, {}) # 每次翻译
t2 = time.perf_counter()
print(t1 - t0, t2 - t1)
实跑输出:
--------------------------------------------------------------------
两种运行方式——编译器与解释器
--------------------------------------------------------------------
同一段源码要跑 2000 次,**编译一次和每次编译差多少?**真的跑一遍:
编译版 翻译 1 次,执行 2000 次 0.041 秒
不编译 翻译 2000 次,执行 2000 次 0.093 秒
多翻译了 1999 次
总时间多了 2.3 倍
方式 翻译几次 执行几次 典型代表
--------------------------------------------------------
编译 1 次 N 次 C/C++/Go
解释 N 次 N 次 早期 BASIC
混合 1 次(到字节码) N 次 Java/Python
**实测多出来的那 1999 次翻译,就是总时间多出来的那一截。**
**所以现代语言大多走第三条路:先翻译成中间代码,再反复执行它。**
**这就是 5.3 的虚拟机。**
实测:翻译 1 次 vs 2000 次,多出来 1999 次——执行都是 2000 次,差的全在翻译上。 所以【解释慢】慢在重复翻译——这也是现代语言都走【编译到中间代码】的原因,下节讲。
30 秒实验
- 用
compile()和直接exec字符串各跑一次,自己量一下倍数。 - 想一想:为什么改了代码不用重启的语言,多半是解释型的。
常见误区
- 以为编译型一定比解释型强。它们是在不同的地方付钱。
- 以为 Python 完全不编译。它先编译成字节码,只是不落成机器码。
自测三问(点开对答案)
1. 编译器和解释器的根本差别是什么? —— 翻译的钱付几次:编译器一次编译、执行 N 次;解释器每次执行都要翻译一次。 2. 实测差在哪? —— 翻译次数 1 次对 2000 次,多出来 1999 次——执行次数一样,翻译差两千倍,总时间因此涨一大截。 3. 混合路线为什么成了主流? —— 先编译成中间代码再反复执行:翻译只付一次,中间代码又不绑 CPU,两头的便宜都拿到。- ☐ 下一节(5.3 解释、运行中间代码的虚拟机)
相关笔记
- 解释、运行中间代码的虚拟机 — 中间代码由谁执行
- 编程语言【退化】了吗 — 这笔账怎么算
- ⚙️ 程序是怎样跑起来的(第3版) · 索引 — 编译与链接的细节
- 🧩 面向对象是怎样工作的 · 索引