【问题标题】:Why does interpreter with JIT produce faster codes than the one without?为什么使用 JIT 的解释器生成的代码比没有 JIT 的解释器更快?
【发布时间】:2012-02-06 00:31:48
【问题描述】:

我仍然不清楚通过 JIT 编译器将字节码编译成机器码的概念。我想知道为什么它比非 JIT 解释器产生更快的代码。有人可以给我一个很好的例子来说明这个过程是如何完成的吗?

【问题讨论】:

  • 因为执行本机机器语言比执行字节码要快。字节码是虚拟机的“机器语言”,但它最终还是会修改内存中的真实数据。 JITting 它允许本地机器代码执行相同的操作。
  • 你能给我一个简短的例子,说明这个“修改内存中的真实数据”是如何完成的(JIT 与非 JIT)?
  • 看一些反汇编的字节码可以看到非JIT版本。查看一些汇编语言以查看 JIT 版本。
  • 您使用什么命令来获取 Java 中的非 JIT / JIT 版本?
  • 您没有获得 JIT 版本(没有一些困难)。 javap -c 反汇编一个类文件并显示字节码。汇编语言的例子无处不在。

标签: java compiler-construction interpreter jit jvm-hotspot


【解决方案1】:

假设你有一个循环需要执行一百万次。

“真正的”解释器需要在循环的每次迭代中查看 this 的字节码,并计算出该代码应该对系统状态(调用等)产生什么影响。

JIT 编译器只查看字节码一次1,然后将其编译为本机代码,然后计算机可以直接理解 - 无需进一步翻译。翻译需要时间,所以如果你能做一次,效率会更高。

举一个现实世界的例子:如果你有一本英文小说,并且有一些法国人对此感兴趣,你可以把这本书交给懂这两种语言的人,他们可以阅读对每个人单独大声朗读。或者,你可以让那个人把这本书拿走,把它翻译成法语,然后给每个法国人一本法语书。如果只有一个人对这本书感兴趣,那么即时翻译会更有效率——不需要编辑、排版专家、打印机等……但如果你有很多人想要读这本书,然后做一个更彻底的一次性翻译 更有意义。


1 一些 JIT,包括 HotSpot 中的 JIT,实际上会根据使用情况以不同的优化级别对相同的代码进行多次 JIT 编译。

【讨论】:

  • 我喜欢你给出的新颖的例子。关于 HotSpot 评论,我假设 JIT 编译相同的代码多次可能是执行程序时的瓶颈,可以吗?我想知道在编译代码时,JIT 编译器与“提前”编译器相比有多快?
  • @tsubasa:只有当 JIT 发现它正在造成瓶颈,并判断它可能值得花更多时间优化时,它才会重新编译它。那里有很多微妙之处,当然有时它会出错,但总的来说还不错:)
  • +1 这个小说的例子似乎是解释 VS 汇编的一个伟大隐喻(JIT 和 AOT 之间的唯一区别是 AOT 出版商在出售书籍之前就翻译了书籍,而 JIT 出版商则在观望哪些翻译可能会出售)。
  • @JonSkeet:+1 除了你的观点,我认为 IL 中的所有程序(例如字节码)只能在一定程度上进行优化,因为它们固有的抽象级别更高。我的意思是因为 java 字节码不是为特定的架构设计的,它们不能被优化到一个很好的水平。结果,解释器应该解释没有很好优化的代码。我说的对吗?
【解决方案2】:

JIT 编译的代码实际上直接在裸机上运行,​​而解释的代码必须不断地由解释器重新解释。解释器不再需要重新处理和重新处理字节码。

【讨论】:

    【解决方案3】:

    编译器将我们的高级源代码翻译成字节码并将字节码翻译成机器码,一些实现有普通的解释器,一些有即时编译器。为了执行一个循环,比如说,百万次,JIT 编译器只将字节码转换为机器码一次,并且对于下一次迭代,机器只理解字节码。而普通解释器,在每次迭代中,重复地将字节码翻译成机器码,因此需要更多的时间来完成一个循环,比如百万次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多