关于 JIT 编译器和解释器的说明

zer*_*uno 5 java interpreter jit

我对 JIT 编译器和解释器有一些疑问。从它们的定义开始:

(翻译)来自维基百科:

在计算机科学中,解释器是直接执行(即执行)以编程或脚本语言编写的指令的计算机程序,无需事先将它们批量编译成机器语言。解释器通常使用以下策略之一来执行程序:
1) 解析源代码并直接执行其行为
2) 将源代码转换为一些有效的中间表示并立即执行
3) 显式执行存储的预编译代码 [1]作为解释器系统一部分的编译器

(JIT 编译器)来自维基百科:

在计算中,即时编译 (JIT),也称为动态翻译,是在程序执行期间(在运行时)而不是在执行之前完成的编译。 [1] 大多数情况下,这包括转换为机器代码,然后直接执行,但也可以指转换为另一种格式。

和来自 StackOverFlow:

即时编译是将非本地代码(例如字节码)在执行之前转换为本地代码。

我有 4 个问题:
1) 总是说 JIT=runtime,为什么解释器在运行时不起作用?当程序运行时,解释器不是在运行时翻译和执行每一行吗?
2) 总是说 JIT 将非本地代码转换为本地代码,那又怎样?解释器不会将代码转换为本机代码吗?如果指令未转换为本地代码,我的进程如何执行该指令?所以解释器也需要将代码翻译成本地代码。
3) 普通解释器在需要执行时翻译每一行,而使用 JIT 编译器时,每一行都在执行前进行翻译,因此在需要执行该行的那一刻是可行的。不是吗?
4) 那么解释器和 JIT 编译器之间的真正区别是什么,两者都在运行时执行程序,都从中间语言翻译为本机代码......

And*_*sen 5

解释器不会将源代码翻译成本地机器代码。虽然您的计算机只能执行机器代码,但它执行的机器代码不一定是高级语言的翻译。令人困惑?让我们看一个简单的玩具示例...

考虑具有两个函数的编程语言PrintForPonyprintsleep. 该print函数将一串字符作为其唯一参数并将其打印到标准输出,同时sleep将一个正整数作为其唯一参数并使当前线程休眠该时间量。PFP 的伪 BNF :

program        ::= statement_list
statement_list ::= statement | statement NEWLINE statement_list
statement      ::= print STRING | sleep POSITIVE_INTEGER
Run Code Online (Sandbox Code Playgroud)

这是PFP 解释器的一个超级简单的 Java 实现。该程序将源文件作为其唯一参数并对其进行解释:

import java.io.BufferedReader;
import java.io.FileReader;

public class PFPInterpreter {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new FileReader(args[0]));
        String line = null;
        while ((line = br.readLine()) != null) {
            if (line.startsWith("print ")) {
                System.out.println(line.substring("print ".length()));
            } else if (line.startsWith("sleep ")) {
                Thread.sleep(Long.parseLong(line.substring("sleep ".length())));
            } else {
                throw new IllegalArgumentException("Unknown function: " + line);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

示例源文件:

print Hello, World!
sleep 1000
print Goodbye, World!
Run Code Online (Sandbox Code Playgroud)

和示例输出:

$ java PFPInterpreter test.pfp 
Hello, World!
Goodbye, World!
Run Code Online (Sandbox Code Playgroud)

PFP 从来没有被翻译成本地机器代码。执行的原生机器码是JVM,与这种玩具语言无关。我们还可以为PFP编写一个编译器,将代码翻译成可执行文件(我不打算这样做,因为这个答案已经太长了),但问题的关键在于解释器不会编译为本机机器代码 - 它读取输入文件并根据内容执行某些操作

回答问题:

1) 解释器是为您运行代码的运行时。我不确定你在哪里读到解释器在运行时不起作用,但我也不确定它应该是什么意思。

2)如上所示,不,解释器不会转换为本地机器代码。JIT 编译器可以。您的处理器仅执行本机机器代码,但本机机器代码可以是读取任意文件并根据内容执行某些操作的程序。从这个意义上说,解释器实际上只是一个典型的程序,它接受文本文件形式的输入。

3) JIT 编译相当复杂,我根本不是专家。然而,例如,对于 Java 的 HotSpot,代码块在 JIT 编译器被调用之前必须执行一定次数(客户端 1,500 次,服务器 15,000 次,IIRC)。这可能是因为实际编译不是免费的,并且很可能将编译的本地机器代码缓存起来以供以后执行(这可以解释多次执行的要求)。这使得JIT编译是投资第一执行(时间和空间),可能无法快(甚至更慢),但后续执行更快,因为编译不再是必要的,且本机代码更有效.

4) 见上文。

我希望这有帮助!