【问题标题】:What are the differences between a Just-in-Time-Compiler and an Interpreter?即时编译器和解释器之间有什么区别?
【发布时间】:2011-01-26 10:24:32
【问题描述】:

Just-in-Time-Compiler 和 Interpreter 有什么区别,.NET 和 Java JIT 编译器有什么区别?

【问题讨论】:

  • 您的问题标题与问题文本不完全匹配。 Java 和 .NET 都是 jitted 的,都不是解释的。
  • 这是第二个问题
  • 那么您应该将其作为第二个不同的问题提出。这样你只会让人们感到困惑。
  • 将两个问题放在一个问题中是有问题的,而仅将一个问题放在标题中更是如此。人们会倾向于搜索标题,因此完全错过了您的第二个问题。查看我写的答案,包括两个已删除的答案,您的第二个问题完全被忽略了。

标签: java .net compiler-construction interpreter jit


【解决方案1】:

我一直发现,更抽象的解释有时会有所帮助。 假设您想问墨西哥的每个人“你好。你好吗?” (您的源语言)当然,您首先需要将其翻译成西班牙语(该国的母语)。那个翻译应该是“Hola. Como estas?”

如果您懂西班牙语,则无需翻译(本机代码/汇编程序)。你只是问“Hola. Como estas?”

如果你不懂西班牙语,有 3 种方法可以解决。

首先是获取一个西班牙语词典(一个编译器),然后在你去之前查一下西班牙语单词是什么。也许你意识到“Hola. Que tal?”是一个音节短(编译器优化),而是使用它。这是语言编译;您事先将信息转换为母语。

第二个是当您站在第一个人面前时查找西班牙语词典中的单词,然后存储结果(查找单词just-in-time)。这样做的好处是你可以获得一本普通话词典,然后在中国做同样的实验,而不必保留十个翻译短语的便笺(不同平台的二进制文件)。

第三个是当你站在每个人面前时查找单词的地方。从本质上讲,您为每个人分别解释单词(您充当解释器)。这里的好处是任何更改都会立即反映到下一个人(您可以更改为询问“您好。您的狗是什么颜色的?”而无需飞回家并重新启动 - 您无需重新编译 短语)。

  • 提前翻译意味着您可以最快地询问他人(预编译);您甚至不需要随身携带字典。
  • 当你看到每个国家的第一个人时翻译几乎和预先翻译一样快,但仍然可以让你去多个国家旅行而无需回家拿字典,但这意味着你需要随身携带几本字典 ( 独立于平台的运行时)。
  • 按需翻译速度要慢得多,但允许您在不回家的情况下更改单词(源分布式语言)。

【讨论】:

  • 太棒了,我喜欢这个答案。其他的都太技术性了,会让非程序员感到困惑。
  • 在中国使用普通话时如何利用存储的(西班牙语)结果?
  • 嗯,我想我明白了……只要我在墨西哥,我就使用存储的结果?
【解决方案2】:

Just-in-time compilation 是在执行之前将非本地代码(例如字节码)转换为本地代码。

来自维基百科:

JIT 建立在运行时环境中的两个早期想法之上:字节码编译和动态编译。它在本机执行之前在运行时转换代码,例如将字节码转换为本机机器码。

interpreter 执行一个程序。它可能有也可能没有抖动。

再次,来自维基百科:

解释器可能是一个程序 要么

  1. 直接执行源代码
  2. 将源代码翻译成一些有效的中间表示 (代码)并立即执行
  3. 显式执行由编译器生成的存储的预编译代码 这是解释器的一部分 系统

标准的 Java 和 .NET 发行版都具有 JIT 编译,但标准并不要求它。 .NET 和 C# 中的 JIT 编译器当然不同,因为中间字节码不同。原理是一样的。

【讨论】:

  • CLR的JIT编译器是否对整个代码进行一次编译?
  • 不,它只编译必要的代码。这为您提供了在运行时进行优化的优势。
  • 但是每次调用的优化过程只发生一次,不是吗(.NET JIT)?因为我红了.NET JIT 只编译了一段代码。
  • 我会说这可能会误导 JIT 等新手,因为它没有明确说明区别:解释器就像使用您的源代码作为指导方针的程序,哪个是“他自己的” " 要调用的子程序。这就是为什么它被称为“解释器”。另一方面,JIT 将您的所有源代码直接转换为原生代码。
  • 第1点和第3点不一样吗?我的意思是解释器如何执行代码而不以某种方式翻译它并使用已经存在的东西?
【解决方案3】:

解释器会为每条指令动态生成和执行机器代码指令,无论它之前是否已执行过。
JIT 缓存先前已解释为机器代码的指令,并重用这些本机机器代码指令,从而无需重新解释已解释的语句,从而节省时间和资源。

【讨论】:

  • 您的答案与 Java JIT 编译器有关,不是吗?
  • 是的,但我相信 JIT 技术最初是在 smalltalk 上开发的。
  • 所以 JIT 会导致程序运行时间越长越快?
  • 不一定,因为程序中可能有一些逻辑导致它变慢。 JIT 不会改变逻辑。但至少,将逻辑转换为机器代码所花费的 CPU 周期成本只会产生一次。
【解决方案4】:

tl;博士

解释器:一次只执行一条指令

Just-in-time:一次获取一段代码并在执行前编译它。所以有很大的优化空间

【讨论】:

  • 所以区别主要在于代码编译优化。对于 JIT,一段经过优化编译的代码,而解释器不做任何优化。
【解决方案5】:

执行引擎是编译器还是解释器的问题可以很简单地通过考虑如果例程执行 1000 次会发生什么来回答。如果执行引擎中的代码必须检查代码的某些特定表示 1,000 次,则执行引擎是该表示的解释器。如果执行中的代码,执行引擎只需检查代码的特定表示的次数较少(通常,但不一定是一次),它是该表示的编译器或翻译器。请注意,执行引擎接受输入代码并将其转换为更容易检查的其他形式是很常见的。这样的执行引擎会将前一种形式的编译器或翻译器与后一种形式的解释器结合起来。

请注意,解释器很少产生任何形式的机器代码。解释器产生机器代码的唯一时间是当语句应该执行一些实际上无法以任何其他方式完成的操作时。例如,如果在 8080 上运行的 BASIC 解释器遇到指令“OUT 100,5”,它通常会通过将 D3 64 C9 (OUT 64h / RET) 存储到某个固定地址的三个连续字节中来执行该操作,加载 A 5,并呼叫该地址。解释器在技术上可能会生成机器代码,但如果要执行相同的 OUT 指令 500 次,解释器每次都必须重新生成机器代码。

【讨论】:

    【解决方案6】:

    JIT 编译器生成二进制机器代码来翻译块源代码。口译员逐行翻译。

    【讨论】:

      【解决方案7】:

      当第一次引用一个类时,JIT 执行引擎将 Java 编译器生成的包含 JVM 指令集的 .class 文件(主二进制文件)重新编译为包含 HOST 系统指令集的二进制文件。 JIT 存储和重用那些从内存中重新编译的二进制文件,从而减少解释时间并从本机代码执行中受益。

      另一方面,一个普通的老式 java 解释器一次解释来自类文件的一条 JVM 指令,并针对它调用一个过程。

      在这里找到详细比较http://bitshub.blogspot.com/2010/01/Flavors-of-JVM.html

      【讨论】:

        【解决方案8】:

        当您编译 Microsoft.NET 语言时,编译器会生成以 Microsoft 中间语言 (MSIL) 编写的代码。 MSIL 是一组指令,可以快速翻译为本机代码。

        Microsoft.NET 应用程序只有在 MSIL 代码被翻译为本机代码后才能运行。在 .NET Framework 中,中间语言在应用程序或组件运行时“即时”(JIT) 编译为本机代码,而不是在开发时编译应用程序。

        more info

        【讨论】:

          猜你喜欢
          • 2010-10-03
          • 2014-08-10
          • 1970-01-01
          • 1970-01-01
          • 2018-07-11
          • 2011-03-26
          • 2021-06-29
          • 1970-01-01
          • 2011-04-19
          相关资源
          最近更新 更多