75

java-classicにはifステートメントの2種類があります:if {} else {}と略称:​​です。他のものよりも速いのですか、それとも同じですか?どちらの "if"構文が高速ですか?ステートメントまたは3項演算子?

声明:

int x; 
if (expression) { 
    x = 1; 
} else { 
    x = 2; 
} 

三項演算子:

int x = (expression) ? 1 : 2; 
+33

私は絶対に違いがないと思っています。それは単なる構文です。コンパイラがやや悪い(または何か他のもの)、私が間違っていない限り、 – sinelaw

+4

(マイクロ)ベンチマークでしたか?結果を共有する。 – BalusC

+3

両方がjitされます。違いは全くありません。そして、そのようなものを逆コンパイルするのは気にしないでください。HotSpotが行う最初のことは、javacによって適用されたすべての**最適化を取り除くことです。 –

答えて

93

「if」文は1つだけあります。もう一つは条件式です。どちらの方がパフォーマンスが向上するかについては、同じバイトコードでコンパイルすることができます。同じように動作することを期待しています。つまり、パフォーマンスの点でどちらかを選択したくないと思います。

時にはif文が読みやすくなります。条件演算子が読みやすくなることがあります。特に、2つのオペランドがシンプルで副作用のない条件付き演算子を使用することをお勧めします。一方、2つのブランチの主目的がの副作用である場合、おそらくifステートメントを使用します。

は、ここでサンプルプログラムとバイトコードです:

public class Test { 
    public static void main(String[] args) { 
     int x; 
     if (args.length > 0) { 
      x = 1; 
     } else { 
      x = 2; 
     } 
    } 

    public static void main2(String[] args) { 
     int x = (args.length > 0) ? 1 : 2; 
    } 
} 

バイトコードはjavap -c Testで逆コンパイル:

public class Test extends java.lang.Object { 
    public Test(); 
    Code: 
     0: aload_0 
     1: invokespecial #1 
     4: return 

    public static void main(java.lang.String[] 
    Code: 
     0: aload_0 
     1: arraylength 
     2: ifle   10 
     5: iconst_1 
     6: istore_1 
     7: goto   12 
     10: iconst_2 
     11: istore_1 
     12: return 

    public static void main2(java.lang.String[ 
    Code: 
     0: aload_0 
     1: arraylength 
     2: ifle   9 
     5: iconst_1 
     6: goto   10 
     9: iconst_2 
     10: istore_1 
     11: return 
} 

を見てわかるように、ここでのバイトコードで若干違いがある - istore_1が発生したかどうか私の以前の大きな欠陥のある試みとは違って:)しかし、JITterが別のネイティブコードで終わったなら、私は非常に驚くだろう。

+0

s /条件文/条件式/ –

+0

@Laurence:Doh - ありがとうございました。 –

+1

「main」と「main2」の両方がまったく同じであることを意味していなかったと思いますか? – ColinD

4

もない - 彼らは同じにコンパイルされます。

10

どちらの例も、おそらく同一またはほぼ同じバイトコードにコンパイルされるため、パフォーマンスに違いはありません。

実行速度に違いがあった場合でも、最も単純な条件と2つの単純なサブ式に基づいて1つの変数を割り当てるための2番目のバージョンと、より複雑な操作や操作を1行に収まらないものにする)。

+0

-1間違っている。 2つのコードが "おそらく"や "私が思う"のような修飾子を与えなくても、同じバイトコードでコンパイルされると主張すれば、少なくとも実際にそうであることを確認することができます。たとえ同じバイトコードでコンパイルしても、他のバージョンのJavaコンパイラが異なるバイトコードにコンパイルされないことは保証されません。 – Brian

+0

@Brian:そうです。私は私の答えを編集しました。 –

+5

OK、私は-1を削除しました:) – Brian

7

これらは同じです。どちらも非常に高速で、通常は約10〜30ナノ秒です。 (使用パターンによって異なります)この時間枠はあなたにとって重要ですか?

あなたはあなたが一番きれいだと思われることを行うべきです。

3

ただ、他のすべての答えに追加する:

第二の発現は、多くの場合、三/三次オペレーター/声明と呼ばれています。これは式を返すので非常に便利です。場合によっては、典型的な短いステートメントではコードをより明確にすることがあります。

+3

実際にこれの大きな例: Javaで、私は式の結果に基づいて文字列ファイナルを作る必要があれば、私は使用することができます三元構文 final String whichTable =(Integer.parseInt(clientId)> 500)? "serverClients": "offlineClients"; 次に、whichTableが最終的である必要がある場所で式の値を使用できます。 以下は違法です: final String whichTable = ""; if(Integer.parseInt(clientId)> 500){ whichTable = "serverClients"; } else { whichTable = "offlineClients"; } –

+0

@JamesPerih正確に。 – Secko

関連する問題