2

三項演算子を使った楽しいテストを次に示します。

public int so( final int a ) {
    int r = (int) System.currentTimeMillis();
    r += a == 2 ? 1 : 0;
    return r;
}

生成されるバイトコードは次のとおりです。

public int doIt(int);
  Code:
   0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
   3:   l2i
   4:   istore_2
   5:   iload_2
   6:   iload_1
   7:   iconst_2
   8:   if_icmpne       15
   11:  iconst_1
   12:  goto    16
   15:  iconst_0
   16:  iadd
   17:  istore_2
   18:  iload_2
   19:  ireturn

「+ 0」の「else」ケースが削除されていないことに少し驚きました。私はこれをもっと期待していました:

public int doIt(int);
  Code:
   0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
   3:   l2i
   4:   istore_2
   5:   iload_1
   6:   iconst_2
   7:   if_icmpne       13
   10:  iinc    2, 1
   13:  iload_2
   14:  ireturn

だからここに私の質問があります:仕様は以下を義務付けていますか?

goto ...
iconst_0

三項演算子を使用したためのシーケンスですか、それともこれは単なるコンパイラの問題ですか?

明らかに、この質問は 'r += ... ? と書くことの関連性に関するものではありません。1:0'. しかし、ここでは最適化を行っていないのに、他のケースではコンパイラがかなりの最適化を行っているので、私は驚いています。

オプション 2 を生成する Java コンパイラは、依然として有効な Java コンパイラでしょうか (例を台無しにしませんでしたが、重要なのは、生成されたコードに不要な 0 の追加と不要な goto がある場合、コンパイラはこれを削除しますか?有効な .java コンパイラである必要があります)?

4

2 に答える 2

3

One thing to keep in mind is that javac (the Java Source code to byte code compiler) is not an optimizing compiler. In fact it is relatively simple in its code generation and only produces the most straight-forward byte-code implementation of any given source code.

That is entirely by design. This way the JVM, which is in charge of all the real optimizations, has the maximum amount of information available on which to base its decisions. In this particular case it might not be obvious how that information can benefit the JIT compiler, but due to the nature of optimizations done by HotSpot for example, every bit of information can help.

For example there might be some smart pattern matching that recognizes common pieces of code and implements them in a highly optimized version. Now if javac tried to do some optimization as well, then those patterns could be much harder to detect.

于 2010-02-23T11:43:40.177 に答える
2

Sun's Javac itself does not do any optimizations as they are left for the HotSpot VM. Thus it produces the first bytecode.

The second bytecode listing is as valid as the first one. So in theory some other Java compiler could produce that.

If that kind of optimizations are needed for VMs that does not have JIT (for example Android devices), there are tools like Proguard that do optimizations on bytecode level.

于 2010-02-23T11:41:50.250 に答える