web-dev-qa-db-ja.com

どちらの「if」構文が高速ですか-ステートメントまたは三項演算子?

Java-classic:if {} else {}と速記:exp ? value1 : value2には、2つのタイプのifステートメントがあります。同じ?

ステートメント:

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

三項演算子:

int x = (expression) ? 1 : 2;
81
Rogach

「if」ステートメントのタイプは1つだけです。もう1つは条件式です。どちらの方がパフォーマンスが良いかについては、同じバイトコードにコンパイルでき、同じように動作することを期待します-または、パフォーマンスの観点から間違いなくどちらかを選択したくないほど近いことを期待します。

ifステートメントの方が読みやすい場合もあれば、条件演算子の方が読みやすい場合もあります。特に、2つのオペランドが単純で副作用がない場合は条件演算子を使用することをお勧めしますが、2つのブランチの主な目的がisの副作用の場合は、おそらく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がbrance内で発生するかどうか(以前の非常に欠陥のある試みとは異なります)。 JITterが異なるネイティブコードで終わった場合。

105
Jon Skeet

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

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

10
Victor Nicollet

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

最も明確だと思うことをすべきです。

8
Peter Lawrey

他のすべての答えに追加するだけです:

2番目の式は、しばしば三次/三次演算子/文と呼ばれます。式を返すため、非常に便利です。場合によっては、一般的な短いステートメントのコードがより明確になります。

4
Secko

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

3
Freddie