7

これは:

int val;  
// ...
val = (val != 0) ? otherVal : 0;

これよりも効率が悪い:

int val;
//...
if (val != 0)
    val = otherVal;

?

コンパイラは三項演算子を最適化できますか? 意図は明らかです。実際にメモリに 0 を書き込む方法はありますか? メモリがファイルにマップされたときでしょうか?

それは問題ではないと仮定できますか?

編集: ポイントは、1 つの条件が満たされた場合に変数を何らかの値に設定することです。他に分岐する必要はありません。そのため、三項 (コピーを作成することになっている必須の else ブランチを使用) の効率が低下したり、最適化されたりするかどうかを尋ねます。

4

5 に答える 5

4

コンパイラが最適化します。結局、パフォーマンスにほとんど差はありません。

ただし、読みやすさには大きな違いがあります。場合によっては、三項演算子を使用すると、明確さをあまり増やさない多くのコード行を削除することができます。

それ以外の場合、ifステートメントはより明確で従うのが簡単です。

コードを 3 項ステートメントに減らしても、明確さを維持するために大量のコメントを追加しなければならないのは逆効果です。

そして、コーディングのすべての神によって、3 項ステートメントを入れ子にしないでください。

于 2013-05-22T16:26:39.417 に答える
4

bitselect ( condition ? true : false ) と呼ばれることもある分岐のない三項演算子を使用できます。

余分な操作について心配する必要はありません。それらは、if ステートメントの分岐に比べれば何でもありません。

ビット選択の実装:

inline static int bitselect(int condition, int truereturnvalue, int falsereturnvalue)
{
    return (truereturnvalue & -condition) | (falsereturnvalue & ~(-condition)); //a when TRUE and b when FALSE
}

inline static float bitselect(int condition, float truereturnvalue, float falsereturnvalue)
{
    //Reinterpret floats. Would work because it's just a bit select, no matter the actual value
    int& at = reinterpret_cast<int&>(truereturnvalue);
    int& af = reinterpret_cast<int&>(falsereturnvalue);
    int res = (at & -condition) | (af & ~(-condition)); //a when TRUE and b when FALSE
    return  reinterpret_cast<float&>(res);
}
于 2015-05-06T18:06:48.227 に答える
2

これは主に三項演算子 ?: vs if...elseの複製です

ほとんどのコンパイラの効率は同じであり、コンパイラは if/else ステートメントを最適化するのと同じように三項演算子を最適化します。そうは言っても、コードを一目で読みやすくする if ステートメントの方が好きです。

あなたの他の質問に答えるために。1 つの整数または変数を 0 に設定するだけの場合、上記のようにゼロに設定する以外に高速な方法はありません。

変数の配列がある場合は、を使用できますmemset(ptr, 0, size*sizeof(TYPE))。これは、ゼロに設定したい変数の配列がある場合におそらく最速です。またはおそらく std::fill_n

上記のロジックで何を達成しようとしているのかはわかりませんが、少し奇妙に思えます。おそらくそこに条件文がまったく必要ないことを意味するコードを配置する方法はありますが、もう少しコードを見ずにあなたの状況について言うのは難しいです.

正直なところ、この操作を何十億回も実行していない限り、これはおそらく時期尚早の最適化であり、読みやすさに集中する必要があります。

于 2013-05-22T16:27:15.347 に答える