Java编译器优化

Mah*_*pta 62 java optimization javac

最近,我正在读这篇文章.

根据那篇文章,Java Compiler即javac在生成字节码时不执行任何优化.这是真的吗?如果是这样,那么它可以作为中间代码生成器实现,以消除冗余并生成最佳代码吗?

Jon*_*eet 82

javac 只会做很少的优化,如果有的话.

关键是JIT编译器完成了大部分优化 - 如果它有大量信息,它会工作得最好,如果javac执行优化,其中一些信息可能会丢失.如果javac执行某种循环展开,JIT就会更难以一般方式执行此操作 - 并且它有更多关于哪些优化将实际起作用的信息,因为它知道目标平台.

  • @Waneck:这是你的意见,但显然不是Java实施团队共享的.如果有的话,`javac`*会做很少的优化.是的,一些优化可能会很昂贵,这就是Hotspot逐步完成的原因.事实上,它使用有关目标环境的更多信息(包括实际加载的类)来执行此操作,这使得它可以执行一些无法静态执行的优化.在某些情况下,AOT优化肯定会更好 - 但反过来也是如此. (21认同)
  • -1用于传播Java神话,编译时优化是不合需要的.一些编译过程可能非常昂贵,并且传播JIT应负责完成所有工作的想法是无稽之谈.事实上,在优化方面,C和C++仍然比Java做得更好. (18认同)
  • 我了解 JIT 编译可以执行编译时无法执行的优化;然而,在编译时不执行任何优化并不是任何借口,这就是我所指的 Java 神话。 (2认同)
  • 以我的经验,Java中最有效的基于编译器的优化涉及通用专业化,内联和避免装箱操作。例如,这份Scala论文http://lampwww.epfl.ch/~dragos/files/scala-spec.pdf显示,执行功能的特殊化导致速度提高20倍,而数组的特殊化导致速度提高40倍。这是一个说明JIT并非圣杯的例子,A​​OT可以与JIT并驾齐驱。 (2认同)

Sim*_*son 26

到达本节时我停止阅读:

更重要的是,javac编译器不执行简单的优化,如循环展开,代数简化,强度降低等.为了获得这些好处和其他简单的优化,程序员必须在Java源代码上执行它们,而不是依靠javac编译器来执行它们.

首先,在Java源代码上进行循环展开几乎不是一个好主意.javac优化方式没有做太多的原因是它由JVM中的JIT编译器完成,它可以做出更好的编译器决策,因为它可以确切地看到哪些代码运行得最多.


man*_*uti 16

所述javac编译器一次支持的选项,通过传递来生成优化代码-o在命令行上.

无论如何启动J2SE1.3,HotSpot JVM随该平台一起提供,该平台引入了动态技术,例如即时编译和公共执行路径的自适应优化.因此,-o启动此版本的Java编译器忽略了它.

在阅读Ant javac任务及其optimize属性时,我遇到了这个标志:

指示是否应使用优化编译源; 默认为off.请注意,Sun javac从JDK 1.3开始忽略了这个标志(因为不需要编译时优化).

此页面中提到了HotSpot JVM的动态优化优于编译时优化的优点:

Server VM包含一个高级自适应编译器,它支持通过优化C++编译器执行的许多相同类型的优化,以及传统编译器无法完成的一些优化,例如跨虚拟方法调用的积极内联.与静态编译器相比,这是一种竞争优势和性能优势.自适应优化技术的方法非常灵活,通常甚至优于高级静态分析和编译技术.


Zom*_*m-B 8

我过去研究过输出的Java字节码(使用名为FrontEnd的应用程序).除了内联常量(静态韵母)和预先计算的固定表达式(如2*5和"ab"+"cd")之外,它基本上不做任何优化.这是为什么如此容易拆解(使用名为JAD的应用程序)的一部分

我还发现了一些有趣的点来优化你的java代码.它帮助我提高了内循环的速度2.5倍.

一个方法有5个快速访问变量.当调用这些变量时,它们比所有其他变量更快(可能是因为堆栈维护).方法的参数也计入这些5.因此,如果你的for循环中的代码执行了一百万次,那么在方法的开头分配这些变量,并且没有参数.

局部变量也比字段快,因此如果在内部循环中使用字段,则通过在方法开头将它们分配给局部变量来缓存这些变量.缓存引用而不是内容.(如:int [] px = this.pixels;)

  • 常量表达式处理(包括最终变量 - 不必是静态的,如果它们具有常量值)实际上由语言规范规定. (3认同)
  • 您能否提供有关这些"5个快速访问变量"的更多信息?我知道[`aload_ <n>`](http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n)字节码指令,但是只有4个,从0到3(对于'astore_ <n>`是相同的).我甚至不确定它们是否比正常的`aload`操作执行得更好(除了它们不需要额外的索引字节,所以安全一些空间).不过,我同意"局部变量与字段"这一论点. (2认同)