web-dev-qa-db-ja.com

三項演算子?:vs if ... else

C++では、?:演算子はif()... elseステートメントよりも高速ですか?コンパイルされたコードでそれらの間に違いはありますか?

66
Xirdus

コンパイラに依存しますが、最新のコンパイラでは一般に違いはありません。心配しないでください。コードの保守性に集中してください。

82
ptomato

速くはありません。式に応じて定数変数を初期化できる場合、1つの違いがあります。

const int x = (a<b) ? b : a;

if-elseで同じことはできません。

93

GCCが条件演算子をcmov(条件付き移動)命令に変換し、ifステートメントをブランチに変換するのを見てきました。つまり、この場合、条件演算子を使用するとコードが高速になります。しかし、それは数年前であり、今日ではほとんどの場合、両方が同じコードにコンパイルされます。

同じコードにコンパイルされるという保証はありません。パフォーマンスが必要な場合は、いつものように、measureです。そして、1。コードが遅すぎること、2。コードの原因がこの特定のコードチャンクであることを測定してわかったら、コンパイラによって生成されたアセンブリコードを調べ、何が起こっているのかを自分で確認します。

「条件演算子を使用すると、コンパイラは常により効率的なコードを生成します」などのゴールデンルールを信頼しないでください。

40
jalf

これらは同じですが、三項演算子はif/elseを使用するのが難しい場所で使用できます。

printf("Total: %d item%s", cnt, cnt != 1 ? "s" : "");

If/elseを使用してこのステートメントを実行すると、非常に異なるコンパイル済みコードが生成されます。


8年後に更新...

実際、これはもっと良いと思います:

printf(cnt == 1 ? "Total: %d item" : "Total: %d items", cnt);

(実際、最初の文字列の「%d」を「one」に置き換えることができると確信しています)

14
James Curran

ちょっと左利きに….

x ? y : x = value

xが0(偽)でない場合、-yvalueを割り当てます。

3
VS3

コンパイルされたコードに関係なく、それらは意味的に異なるものです。 <cond>?<true expr>:<false expr>は式であり、if..else..はステートメントです。

条件式の構文は厄介に思えますが、良いことです。 <false expr>を指定する必要があり、2つの式は型チェックされます。

LISPなどの式ベースの関数型言語のif..else..と同等のHaskellは、? :ステートメントではなく、C++のif..else..です。

2
amdyes

すべてを1行に入れる必要はありません。

x = y==1 ?
    2
    :// else
    3;

両方のブランチがxに割り当てられていることがすぐにわかるため、if/elseよりもはるかに明確です。

1
QuentinUK

三項演算子は常に値を返します。したがって、結果から何らかの出力値が必要な状況で、三項演算子を使用するのが常に2つの条件しかない場合です。上記の条件のいずれかが当てはまらない場合は、if-elseを使用します。

0
Raheel Afzal

今、私はそれであなたを助けることができません、私はその下の二次的な質問で助けることができるかもしれません、私はそれを使いたいですか?速度だけを知りたい場合は、私のコメントを無視してください。

私が言うことができるのは、三元をいつ使用するかについて非常に賢明であるということですか? :演算子。それは読みやすさの呪いと同じくらい祝福でありえます。

これを使用する前に読みやすいかどうかを自問してください

int x = x == 1 ? x = 1 : x = 1;

if (x == 1)
{
   x = 1
}
else
{
   x = 2
}

if (x == 1)
    x = 1
else
    x = 1

はい、コードを100%偽物にするのは愚かに見えます。しかし、その小さなトリックは、コードの可読性を分析するのに役立ちました。これは、このサンプルで見ているオペレーターの読みやすさであり、コンテンツではありません。

それはきれいに見えますが、平均的な便座とドアノブもそうです

私の経験では、限られていますが、実際には、三項演算子から必要な情報を迅速に引き出せる人はほとんどいません。バグがある場合でも修正するのは苦痛です

0
Proclyon

ほとんどのコンパイラとターゲットプラットフォームでは、「if」の方が速い場合と、?:の方が速い場合があります。 1つのフォームが他のフォームよりも多かれ少なかれコンパクトになる場合もあります。どちらの形式が好ましいかは、コンパイラとプラットフォームによって異なります。組み込みマイクロでパフォーマンスが重要なコードを書いている場合は、それぞれの場合にコンパイラーが生成しているものを見て、どちらが優れているかを確認してください。 「メインストリーム」PCでは、キャッシュの問題のため、どちらが優れているかを確認する唯一の方法は、両方のフォームを実際のアプリケーションに似たものでベンチマークすることです。

0
supercat

Cでは、三項演算子「?:」を使用して、次の形式の条件式を作成できます。

exp1 ? exp2:exp3

exp1、exp2およびexp3は式です

例えば

        a=20;
        b=25;
        x=(a>b)?a:b;

        in the above example x value will be assigned to b;

これはif..elseステートメントを使用して次のように記述できます。

            if (a>b)
             x=a;
             else
             x=b;

**したがって、これら2つの間に違いはありません。プログラマーにとっては簡単に記述できますが、コンパイラーにとっては同じです。*

0
ksrao

インラインifが動作するスコープのために「より速い」コードを生成できる状況があると思います。オブジェクトの作成と破棄にはコストがかかるため、次のシナリオを検討してください。

class A{
    public:
    A() : value(0) {
        cout << "Default ctor" << endl;
    }
    A(int myInt) : value(myInt)
    {
        cout << "Overloaded ctor" << endl;
    }

    A& operator=(const A& other){
        cout << "= operator" << endl;
        value = other.value; 
    }

    ~A(){
        cout << "destroyed" << std::endl;
    }

    int value;

};


int main()
{
   {
       A a;
       if(true){
           a = A(5);
       }else{
           a = A(10);
       }
   }

   cout << "Next test" << endl;
   {
        A b = true? A(5) : A(10);
   }
   return 0;
}

このコードでは、出力は次のようになります。

Default ctor                                                                                                                                                                                                                      
Overloaded ctor                                                                                                                                                                                                                   
= operator                                                                                                                                                                                                                        
destroyed                                                                                                                                                                                                                         
destroyed                                                                                                                                                                                                                         
Next test                                                                                                                                                                                                                         
Overloaded ctor                                                                                                                                                                                                                   
destroyed  

したがって、ifをインライン化することにより、aと同じスコープでbを存続させるために必要な一連の操作を保存します。両方のシナリオで条件評価の速度がほぼ等しい可能性は非常に高いですが、スコープを変更すると、インラインifで回避できる他の要因を考慮する必要があります。

0
Eric

いくつかのコードを反転させている間(数年前は覚えていませんが)、Machine Code ::?およびif-else。 Don't remember much but it is clear that implementation of both is different.

しかし、効率の良さからコードの読みやすさや利便性に応じて選択することはお勧めしません。ハッピーコーディング

0
Pervez Alam