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

标签 java interpreter jit

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

(解释器) 来自维基百科:

In computer science, an interpreter is a computer program that directly executes, i.e. performs, instructions written in a programming or scripting language, without previously batch-compiling them into machine language. An interpreter generally uses one of the following strategies for program execution:
1) parse the source code and perform its behavior directly
2) translate source code into some efficient intermediate representation and immediately execute this
3) explicitly execute stored precompiled code[1] made by a compiler which is part of the interpreter system

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

In computing, just-in-time compilation (JIT), also known as dynamic translation, is compilation done during execution of a program – at run time – rather than prior to execution.[1] Most often this consists of translation to machine code, which is then executed directly, but can also refer to translation to another format.

来自 StackOverFlow:

Just-in-time compilation is the conversion of non-native code, for example bytecode, into native code just before it is executed.

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

最佳答案

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

考虑具有两个功能的编程语言 PrintForPonyprintsleepprint 函数将一串字符作为其唯一参数并将其打印到标准输出,而 sleep 将正整数作为其唯一参数并使当前线程 hibernate 一段时间那段时间。 PFP 的伪 BNF:

program        ::= statement_list
statement_list ::= statement | statement NEWLINE statement_list
statement      ::= print STRING | sleep POSITIVE_INTEGER

这是PFP 解释器的 super 简单 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);
            }
        }
    }
}

示例源文件:

print Hello, World!
sleep 1000
print Goodbye, World!

和示例输出:

$ java PFPInterpreter test.pfp 
Hello, World!
Goodbye, World!

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

回答问题:

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

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

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

4) 见上文。

希望对您有所帮助!

关于java - 关于 JIT 编译器和解释器的说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23417218/

相关文章:

java - 如何在 CoreNLP 中将字符串传递给 AbstractSequenceClassifier.classifyAndWriteAnswersKBest?

java - 在 Java 中将制表符作为命令行参数传递

php - 为什么PHP允许抽象静态函数

llvm 用另一个函数替换一个函数

assembly - Commodore PET BASIC 从 $00C2 开始组装什么?

java - 未知错误: call function result missing 'value' Appium Hybrid App

java - hibernate 不只存储午夜的详细日期

Racket - 制作关闭和应用关闭

interpreter - 是否可以在我的软件中嵌入 LLVM 解释器,这是否有意义?

c++ - 应该如何设置王朝?