Python 解释器
1 作为一个解释型的语言...
像C/C++/Rust这些语言直接编译成机器玛运行,是编译型语言,Python 的运行过程是虚拟机读入 Python代码(文本),词法分析,编译成虚拟机认识的 opcode ,然后虚拟机解释器 opcode 执行,但这其实不是主要的原因, Python import之后会缓存编译后的 opcode,(pyc 文件或者 __pycache__ 文件夹)。所以读入,此法分析和编译并没有占太多的时间。
那真正慢的是那一部分呢? 就是后面虚拟机解释 opcode 执行的部分。前期的编译是将Python 代码编译成解释器可以理解的中间代码,解释器在将中间代码翻译成 CPU 可以理解的指令。相比于 AOT (提前编译型语言,比如C)直接编译成机器码,肯定慢的。
2 但是为什么java 不满呢?
因为java有JIT。即使编译技术将代码分成frames,AOT 编译器负责在运行时将中间代码翻译成 CPU 可以理解的代码,这一部分跟Python的解释器没有台大区别,依然是翻译中间代码,执行,真正快的地方是,JIT 可以在运行是作优化,比如虚拟机发现一段代码在频繁执行(大多数情况喜爱我们的程序都在反复执行一段代码),就会开始优化,将这段代码用更改的版本替换掉,这是仅有虚拟机语言才有的优势,因为要收集运行时信息。像 gcc 这种 AOT 编译器,只能基于景泰分析做一些分析。
3 为什么Python 没有JIT呢?
第一是 JIT 开发成本比较高,费城复杂。C# 也有很好的 JIT ,应为微软有钱。
第二是 JIT 启动速度慢, java 和 C# 虚拟机启动很多,CPython 也很慢,Pypy 有 JIT ,它比CPython 还要慢 2x - 3x。长期运行的程序来说,启动慢一些没有什么,毕竟运行时间长了之后代码会变快,收益更高。但是 CPython 是通用目的的虚拟机,像命令行程序来说,启动速度慢体验就差很多了。
第三 java 和 C#是静态类型的虚拟机,编译器可以做一些假设。
动态类型
静态类型的语言比如 C,java 、Go,需要在声明变量的时带上类型。而Python 就不用,Python 帮你决定一个变量是什么类型,并且可以随意更改。
动态类型为什么慢呢? 每次检查类型和改变类型开销大,如此动态类型,难以优化。
动态类型带来的好处是,写起来非常简单,符合直觉,可以在运行是修改对象的行为, Monkey Patch 非常简单。
近几年的语言都是静态类型的,比如Go,Rust,静态类型不仅对编译器来说更友好,对程序员来说更好维护。