2016-08-11 11 views
-1

ここでは、Javaコンパイルの最適化に関する簡単な質問があります。コンパイル時のJava定数式関連コードの最適化

は、パフォーマンスの面でコードをコンパイルするか、一般的に

final int CONSTANT_NUMBER=7; 

に等しい

final int CONSTANT_NUMBER="Foo Bar".length(); 

ですか?

+0

フィールドに書き込まれるだけ定数の第二の場合に

7: invokevirtual #3 // Method java/lang/String.length:()I 

存在しますコードのコンパイルとパフォーマンスが同じではありません。 – Blobonat

+0

もちろん、他のものに強く影響するものがあります。 – LapisSea

答えて

2

いいえJavaコンパイラはコンパイル時に"Foo Bar".length()を評価しません。

.length()コールが保たれていることを、あなたが見ることができるコンパイル.classファイルにjavap -vを使用して、これらのクラス

public class ConstantCheck { 

    final int CONSTANT_NUMBER = "Foo Bar".length(); 
} 

public class ConstantCheck { 

    final int CONSTANT_NUMBER = 7; 
} 

考えてみましょう:

で旧結果

... 

    final int CONSTANT_NUMBER; 
    descriptor: I 
    flags: ACC_FINAL 

    public text.ConstantCheck(); 
    descriptor:()V 
    flags: ACC_PUBLIC 
    Code: 
     stack=2, locals=1, args_size=1 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>":()V 
     4: aload_0 
     5: ldc   #2     // String Foo Bar 
     7: invokevirtual #3     // Method java/lang/String.length:()I 
     10: putfield  #4     // Field CONSTANT_NUMBER:I 
     13: return 
... 

後者の最初のケースで

... 

    final int CONSTANT_NUMBER; 
    descriptor: I 
    flags: ACC_FINAL 
    ConstantValue: int 7 

    public text.ConstantCheck(); 
    descriptor:()V 
    flags: ACC_PUBLIC 
    Code: 
     stack=2, locals=1, args_size=1 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>":()V 
     4: aload_0 
     5: bipush  7 
     7: putfield  #2     // Field CONSTANT_NUMBER:I 
     10: return 
    .... 

.lengthコールは、それが

5: bipush  7 
7: putfield  #2     // Field CONSTANT_NUMBER:I 
+0

ええ、それを見るのは残念です。私はコンパイラがそのようなコードを検出できると思った。 – LapisSea

1

コンパイルからは、最初はメソッド呼び出しがあるので、2番目のメソッドは少し高速になります。しかし、今日のマシンは、これが目立つかまたは重要であるほど早すぎます。

性能について - 現代のコンパイラは "Foo Bar"が定数であり、式をlengthに置き換える必要があることを知るためにはスマートでなければなりません。しかし、変数を変数に変更した場合は、毎回メソッドを呼び出すようにコンパイラをだますことができます。大きなループで実行すると、最初に少し速くなります。

私は大きなループで実行させることでこれをテストし、2番目の方法ではパフォーマンスがやや向上しました。私のコンパイラはメソッド呼び出しを定数で置き換えるほどスマートではないと思います。

私のマシン上でのメソッド呼び出しよりもパフォーマンスが良い、直接的なint型のほうが優れていますが、別のコンパイラでは異なることがあります。

+0

ありがとう!それはまさに私が探していたものです! :D – LapisSea

関連する問題