即时编译器(Just-in-Time-Compiler)和解释器(Interpreter)有什么区别?.NET 和 Java 的 JIT 编译器之间有差异吗?
即时编译器(Just-in-Time-Compiler)和解释器(Interpreter)有什么区别?.NET 和 Java 的 JIT 编译器之间有差异吗?
我发现有时候更抽象的解释会更有帮助。假设你想问墨西哥每个人“你好,你怎么样?”(你的源语言),当然,你首先需要将它翻译成该国的本地语言——西班牙语。这个翻译是“Hola. Como estas?"。
如果你懂西班牙语,那么就不需要进行翻译(本地代码/汇编语言)。你可以直接说“Hola. Como estas?"。
如果你不懂西班牙语,有三种处理方式。
第一种是使用西班牙语词典(一个编译器)在旅行前查询西班牙语单词。也许你发现“Hola. Que tal?"比原句短一个音节(编译器优化),于是你就用了这个短一些的短语。这称作语言编译;你事先将信息转换为本地语言。
第二种方法是你在面对第一个人时,在西班牙语词典中查找单词并记录下来(即时编译)。其优势在于你可以使用普通话词典,然后在中国做同样的实验,而不必带着十张便利贴(不同平台的二进制文件)记录翻译短语。
第三种方法是你在面对每个人时查询单词。本质上,你为每个人单独解释单词(你扮演口译者)。其优势在于任何更改都会立即反映在下一个人身上(你可以改成问“你好。你的狗是什么颜色?”而不需要飞回家并重新开始——你不需要重新编译这些短语)。
即时编译是将非本地代码(例如字节码)转换为本地代码,仅在执行之前进行。
维基百科介绍如下:
JIT 建立在运行时环境中两个早期想法的基础上:字节码编译和动态编译。它在运行时将代码转换为本机代码,例如将字节码转换为本机机器代码,然后再执行。
解释器执行程序。它可能具有JIT,也可能没有。
同样来自维基百科:
解释器可能是一个程序,
- 直接执行源代码
- 将源代码翻译成一些有效的中间表示形式(代码),然后立即执行此代码
- 明确地执行由解释器系统的编译器创建的存储的预编译代码
标准的Java和.NET发行版都具有JIT编译,但这不是标准所要求的。.NET和C#中的JIT编译器当然是不同的,因为中间字节码是不同的,但原理是相同的。
解释器会为每个指令即时生成并执行机器码指令,无论该指令是否已经被执行过。
JIT 会缓存已经被翻译成机器码的指令,并重复使用这些本地机器码指令,从而节省时间和资源,无需重新解释已经被解释过的语句。
简而言之:
解释器:一次只能执行一条指令。
即时编译:一次性接收一整块代码,并在执行前编译。因此有更多的优化空间。
JIT编译器生成将块源代码转换为二进制机器码。解释器逐行翻译。
当您编译 Microsoft.NET 语言时,编译器会生成用 Microsoft Intermediate Language (MSIL) 编写的代码。MSIL 是一组指令,可以快速转换为本机代码。
只有在将 MSIL 代码转换为本机机器代码后,Microsoft.NET 应用程序才能运行。在 .NET Framework 中,中间语言在应用程序或组件运行时即时编译成本机代码(JIT),而不是在开发时编译应用程序。