相同版本的Oracle编译器、Apache编译器、IBM编译器、OpenJDK Java编译器在代码优化方面有什么不同吗?如果有什么代码将演示不同的优化?或者他们使用的是同一个编译器?如果没有已知的优化差异,那么我在哪里可以找到有关如何测试编译器以进行不同优化的资源呢?
发布于 2013-10-02 08:17:51
相同版本的Oracle编译器、Apache编译器、IBM编译器、OpenJDK Java编译器在代码优化方面有什么不同吗?
虽然编译器可能有很大的不同,但javac几乎不进行优化。主要的优化是常量内联,这是在JLS中指定的,因此是标准的(除了任何bug)。
如果有什么代码将演示不同的优化?
你可以做到这一点。
final String w = "world";
String a = "hello " + w;
String b = "hello world";
String c = w;
String d = "hello " + c;
System.out.prinlnt(a == b); // these are the same String
System.out.prinlnt(c == b); // these are NOT the same String在第一种情况下,常量是内联的,字符串在编译时连在一起。在第二种情况下,连接在运行时执行,并创建了一个新字符串。
或者他们使用的是同一个编译器?
没有,但是99%的优化都是由JIT在运行时执行的,因此对于给定版本的JVM,它们是相同的。
如果没有已知的优化差异,那么我在哪里可以找到有关如何测试编译器以进行不同优化的资源呢?
如果有一个,我会感到惊讶,因为这听起来不太有用。问题是,JIT优化了预先构建的字节代码模板,如果您试图优化字节代码,您最终可能会混淆JIT,而代码会变慢。也就是说,如果不考虑JVM的运行,就无法评估优化。
发布于 2013-10-02 08:07:40
不,他们不使用相同的编译器。我不能对优化和内容发表太多评论,但是这里有一个例子,编译器的工作方式是不同的。
public class Test {
public static void main(String[] args) {
int x = 1L; // <- this cannot compile
}
}如果使用标准的java编译器,它将引发编译错误,类文件将不会被创建。
但是,如果您为java 欧洲法院使用eclipse编译器,它不仅会抛出相同的编译错误,而且还会创建一个类文件(YES,用于不可编译代码的类文件,这使ECJ (我不会说错,但有点棘手)看起来如下所示。
public static void main(String[] paramArrayOfString)
{
throw new Error("Unresolved compilation problem: \n\tType mismatch: cannot convert from long to int.\n");
}话虽如此,这只是两个编译器之间的问题。其他编译器可能有自己的工作方式。
P.S: --我从这里那里拿了这个例子。
发布于 2013-10-04 18:57:53
我花了很多时间与之打交道的唯一编译器是javac (正如其他人所指出的,它在急切的优化方面做得很少)和Eclipse编译器。
在编写Java反编译程序时,我观察到Eclipse编译代码的方式有一些差异(经常令人沮丧),但并不多。其中一些可以被认为是优化。其中:
javac执行这种类型的优化;将始终发出等效的块。我记得的所有示例都发生在switch语句中。这种优化减少了方法的大小(因此也减少了类文件的大小),这可能会增加加载和验证时间。它甚至可能导致在解释模式下的性能改善(特别是当所讨论的解释器执行内联时),但我认为这样的改进会很小。我怀疑一旦JIT编译了这个方法,它就会有什么不同。它还使反编译更加困难(grrr)。javac完全不同的顺序发出。这可能只是编译器内部设计的副作用,也可能是编译器试图优化代码布局以减少跳转次数。这是我通常会留给JIT的那种优化,这种哲学似乎对javac很好。https://stackoverflow.com/questions/19132420
复制相似问题