与传统编译器相比,JIT编译器是否有任何缺点?

时间:2010-07-11 04:29:03

标签: compiler-construction jit

  

可能重复:
  JIT compiler vs offline compilers

所以直到几分钟前我才真正理解JIT编译器和解释器之间的区别是什么。浏览SO,我找到了答案,提出了标题中的问题。据我所知,JIT编译器具有能够使用其运行的特定处理器的优点,因此可以制作更好的优化程序。有人可以给我一个比较各自的利弊吗?

6 个答案:

答案 0 :(得分:11)

Interpreter,JIT编译器和“离线”编译器

  

JIT编译器和   解释

为了简单起见,我们只是说解释器将运行字节码(中间代码/语言)。当VM /解释器决定最好这样做时,JIT编译机制会将相同的字节码转换为有问题的硬件的本机代码,重点关注所请求的优化类型。

  

所以基本上JIT可能会产生一个   更快的可执行文件但更长时间   编译?

我认为你缺少的是JIT编译发生在运行时而不是编译时间(不像“离线”编译器)

JIT编译具有开销

编译代码不是免费的,也需要时间。如果它投入时间进行编译,然后只运行几次,那么它可能没有进行过良好的交易。因此VM仍然必须决定将什么定义为“热点”并JIT编译它。

请允许我举例说明Java虚拟机(JVM):

JVM可以使用开关来定义阈值,在此之后代码将被JIT编译。 -XX:CompileThreshold=10000

为了说明JIT编译时间的成本,假设您将该阈值设置为20,并且有一段需要运行21次的代码。发生的事情是它运行20次之后,VM现在会投入一些时间进行JIT编译。现在你有来自JIT编译的本机代码,但它只会运行一次(21),这可能不会带来任何性能提升来弥补JIT进程。

我希望这能说明一切。

这是一个JVM开关,显示在JIT编译上花费的时间-XX:-CITime“打印在JIT编译器中花费的时间”

旁注:我不认为这是一个“大问题”,只是在你提出这个问题之后我想指出的。

答案 1 :(得分:2)

对我而言,至少缺乏内联ASM是一个很大的问题。偶尔,您只需要完全控制程序的一小部分CPU的每个细节。即使我不需要手头的任务,我也喜欢这样的想法,即我的计算机所能做的一切都可以,原则上可以用我的语言完成。

答案 2 :(得分:1)

JIT编译器有更多的内存开销,因为除了运行时库和AOT(提前编译)程序所需的编译代码之外,它们还需要加载编译器和解释器。

答案 3 :(得分:1)

JIT编译本身并不意味着它很容易被反汇编。这更依赖于实现,例如Java二进制文件。但请注意,JIT可以应用于任何类型的可执行文件,无论是Java,Python还是已经编译过的C ++或类似的二进制文件。 (IIRC,Dynamo项目涉及重新编译此类二进制文件以提高性能。)

JIT编译的权衡是,虽然进程的目标是提高运行时性能,但该进程实际上也是在运行时进行的,因此在分析,编译和验证代码片段时会产生开销。如果实现效率低下或者没有进行足够的优化,那么它实际上会导致性能下降。

另一个权衡是,在某些情况下,JIT编译可能非常浪费。例如,考虑一个自修改的可执行文件。如果编译代码片段,然后可执行文件修改该片段,则必须丢弃已编译的片段,然后重新分析该片段以确定是否值得重新编译。如果经常发生这种情况,会有很大的性能损失。

最后,内存消耗受到打击,因为编译后的代码片段必须驻留在内存中才能生效。这可能会使内存容量有限的设备变得不切实际,或者很难很好地实现。

答案 4 :(得分:0)

我想说使用JIT编译器的一个真正的缺点(更多的是副作用),就是将IL拆分成人类可读的代码很容易。

答案 5 :(得分:0)

JIT编译器更难写(不是整个故事,但值得一提)。