首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译器- java有区别吗?

编译器- java有区别吗?
EN

Stack Overflow用户
提问于 2013-10-02 08:00:08
回答 3查看 198关注 0票数 4

相同版本的Oracle编译器、Apache编译器、IBM编译器、OpenJDK Java编译器在代码优化方面有什么不同吗?如果有什么代码将演示不同的优化?或者他们使用的是同一个编译器?如果没有已知的优化差异,那么我在哪里可以找到有关如何测试编译器以进行不同优化的资源呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-10-02 08:17:51

相同版本的Oracle编译器、Apache编译器、IBM编译器、OpenJDK Java编译器在代码优化方面有什么不同吗?

虽然编译器可能有很大的不同,但javac几乎不进行优化。主要的优化是常量内联,这是在JLS中指定的,因此是标准的(除了任何bug)。

如果有什么代码将演示不同的优化?

你可以做到这一点。

代码语言:javascript
复制
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的运行,就无法评估优化。

票数 3
EN

Stack Overflow用户

发布于 2013-10-02 08:07:40

不,他们不使用相同的编译器。我不能对优化和内容发表太多评论,但是这里有一个例子,编译器的工作方式是不同的。

代码语言:javascript
复制
public class Test {
    public static void main(String[] args) {
        int x = 1L;  // <- this cannot compile
    }
}

如果使用标准的java编译器,它将引发编译错误,类文件将不会被创建。

但是,如果您为java 欧洲法院使用eclipse编译器,它不仅会抛出相同的编译错误,而且还会创建一个类文件(YES,用于不可编译代码的类文件,这使ECJ (我不会说错,但有点棘手)看起来如下所示。

代码语言:javascript
复制
public static void main(String[] paramArrayOfString)
{
    throw new Error("Unresolved compilation problem: \n\tType mismatch: cannot convert from long to int.\n");
}

话虽如此,这只是两个编译器之间的问题。其他编译器可能有自己的工作方式。

P.S: --我从这里那里拿了这个例子。

票数 3
EN

Stack Overflow用户

发布于 2013-10-04 18:57:53

我花了很多时间与之打交道的唯一编译器是javac (正如其他人所指出的,它在急切的优化方面做得很少)和Eclipse编译器。

在编写Java反编译程序时,我观察到Eclipse编译代码的方式有一些差异(经常令人沮丧),但并不多。其中一些可以被认为是优化。其中:

  1. Eclipse编译器似乎至少执行了一些重复的代码分析。如果两个(或更多?)代码块两个分支都可以分离但等效的代码块,等效的目标块可以通过多个条目跳转平坦成单个块。我从未见过javac执行这种类型的优化;将始终发出等效的块。我记得的所有示例都发生在switch语句中。这种优化减少了方法的大小(因此也减少了类文件的大小),这可能会增加加载和验证时间。它甚至可能导致在解释模式下的性能改善(特别是当所讨论的解释器执行内联时),但我认为这样的改进会很小。我怀疑一旦JIT编译了这个方法,它就会有什么不同。它还使反编译更加困难(grrr)。
  2. 基本块通常以与javac完全不同的顺序发出。这可能只是编译器内部设计的副作用,也可能是编译器试图优化代码布局以减少跳转次数。这是我通常会留给JIT的那种优化,这种哲学似乎对javac很好。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19132420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档