web-dev-qa-db-ja.com

Javaの「if」条件よりも三項演算子が速い

私は「if-conditional syndrome」になりやすいので、常にif条件を使用する傾向があります。私はめったに三項演算子を使用しません。例えば:

//I like to do this:
int a;
if (i == 0)
{
    a = 10;
}
else
{
    a = 5;
}

//When I could do this:
int a = (i == 0) ? 10:5;

どちらを使用するかは重要ですか?どちらが速いですか?顕著なパフォーマンスの違いはありますか?可能な限り最短のコードを使用することをお勧めしますか?

109
JRunner

どちらを使用するかは重要ですか?

はい! 2番目は非常に読みやすいです。必要なものを簡潔に表現した1行を、9行の効果的に乱雑に交換しています。

どちらが速いですか?

どちらでもない。

可能な限り最短のコードを使用することをお勧めしますか?

「可能な限り」ではありませんが、可能な限り、有害な影響なしに可能な限り確実に。短いコードは、付随的な影響ではなく関連する部分に焦点を合わせているため、少なくとも潜在的に読みやすくなります(「定型コード」)。

100
Konrad Rudolph

anyパフォーマンスの違いがある場合(疑わしい)、それは無視できます。できる限りシンプルで読みやすいコードを書くことに集中してください。

そうは言っても、条件演算子の嫌悪感を乗り越えてみてください-確かに使いすぎる可能性はありますが、場合によっては本当に役に立つかもしれません。あなたが与えた特定の例では、必ず条件演算子を使用します。

31
Jon Skeet

三項演算子の例:

int a = (i == 0) ? 10 : 5;

次のようなif/elseを使用した割り当てはできません。

// invalid:
int a = if (i == 0) 10; else 5;

これは、三項演算子を使用する正当な理由です。課題がない場合:

(i == 0) ? foo () : bar ();

if/elseはそれほど多くのコードではありません:

if (i == 0) foo (); else bar ();

パフォーマンスが重要な場合:測定します。ボトルネックがある場合は、通常のデータを使用して、ターゲットマシン、ターゲットJVMで測定します。それ以外の場合は、読みやすくします。

コンテキストに埋め込まれた短い形式は非常に便利な場合があります。

System.out.println ("Good morning " + (p.female ? "Miss " : "Mister ") + p.getName ()); 
27
user unknown

はい、それは重要ですが、コード実行のパフォーマンスのためではありません。

より高速な(パフォーマンスの)コーディングは、単純な構文構造よりもループとオブジェクトのインスタンス化に関連しています。コンパイラは最適化を処理する必要があります(すべて同じバイナリになります!)目標はYou-From-The-Futureの効率です(人間は常にソフトウェアのボトルネックです)。

Parleys.comでのJosh Blochの「Performance Anxiety」トーク

1行に対して9行を引用する答えは誤解を招く可能性があります。コードの行数が少ないほど良いとは限りません。三項演算子は、限られた状況でより簡潔な方法にすることができます(あなたの例は良い例です)。

しかし、彼らはしばしばコードを読めないようにするために乱用される可能性があります(これは重大な罪です)=三項演算子をネストしないでください!

また、将来の保守性を考慮してください。if-elseを使用すると、拡張または変更がはるかに簡単になります。

int a;
if ( i != 0 && k == 7 ){
    a = 10;
    logger.debug( "debug message here" );
}else
    a = 3;
    logger.debug( "other debug message here" );
}


int a = (i != 0 && k== 7 ) ? 10 : 3;  // density without logging nor ability to use breakpoints

追伸 三元に、または三元にしない? での非常に完全なstackoverflowの答え

15
foupfeiffer

三項演算子は簡単なものです。これらは同等のif-elseステートメントにコンパイルされます。つまり、正確に同じになります。

8
Jon Egeland

また、三項演算子は、「オプション」パラメーターの形式を有効にします。 Javaでは、メソッドシグネチャでオプションのパラメーターを使用できませんが、nullがパラメーター値に指定されている場合、三項演算子を使用すると、デフォルトの選択肢を簡単にインライン化できます。

例えば:

public void myMethod(int par1, String optionalPar2) {

    String par2 = ((optionalPar2 == null) ? getDefaultString() : optionalPar2)
            .trim()
            .toUpperCase(getDefaultLocale());
}

上記の例では、nullStringパラメーター値として渡すと、NullPointerExceptionの代わりにデフォルトのストリング値が取得されます。短くて甘く、とても読みやすいと思います。さらに、指摘されているように、バイトコードレベルでは、三項演算子とif-then-elseの間に実際の違いはありません。上記の例のように、選択する決定は完全に読みやすさに基づいています。

さらに、このパターンを使用すると、次のようにメソッドをオーバーロードすることで、Stringパラメーターを本当にオプションにすることができます(そうすることが有用であると思われる場合)。

public void myMethod(int par1) {
    return myMethod(par1, null);
}
4
scottb

与えられた例では、特定の理由で三項演算子または条件演算子(?)を好みます。aの割り当てはオプションではないことがはっきりとわかります。簡単な例では、if-elseブロックをスキャンしてaが各句に割り当てられていることを確認するのはそれほど難しくありませんが、各句にいくつかの割り当てがあることを想像してください。

if (i == 0)
{
    a = 10;
    b = 6;
    c = 3;
}
else
{
    a = 5;
    b = 4;
    d = 1;
}

a = (i == 0) ? 10 : 5;
b = (i == 0) ? 6  : 4;
c = (i == 0) ? 3  : 9;
d = (i == 0) ? 12 : 1;

私は後者を好むので、あなたはあなたが課題を見逃していないことを知っています。

1
Matthew Carlson

読みやすいものであれば何でも使用するのが最善です-実際のパフォーマンスには、パフォーマンスに0の違いがあります。

この場合、最後のステートメントの方が最初のifステートメントよりも読みやすいと思いますが、三項演算子を使いすぎないように注意してください。

0
Michael Berry

switch caseステートメントを使用してみますが、通常はパフォーマンスのボトルネックではありません。

0
Zava