1

次の 2 つのケースの間にパフォーマンスの違いはありますか:
最初:

int test_some_condition(void);

if( some_variable == 2 && test_some_condition())
{
    //body
}

2番:

int test_some_condition(void);

if( some_variable == 2 )
{
    if(test_some_condition())
    {
        //body
    }
}

更新:テストを作成して各ケースのパフォーマンスを測定する方法、または各ケースで生成されたアセンブリを確認する方法を知っていますが、この質問に出くわしたのは私が初めてではないと確信しています。すでにテスト済みで、単純なはい/いいえの答えになる可能性があります。

4

6 に答える 6

4

何の違い?

読みやすさ?はい、違いがあります。最初のものははるかに明確で、あなたの意図をはるかによく表現しています。また、エディターで必要な行数が少なくなるため、それ自体が必ずしも利点とは限りませんが、コードを読みやすくし、編集したい人にとっては一目でわかりやすくなります。

パフォーマンス/「スピード」?いいえ。最適化をオンにしてコンパイラーでこれらの2つのコードスニペットを実行すると、認識できる違いはまったくないという実際のお金を賭けても構わないと思います。そして、最適化が無効になっている場合でも、同じケースに賭けるように私を説得するのにそれほど時間はかかりません。

なんで?C(および私が知っているすべてのC派生言語)では、&&演算子が短絡評価を実行するため、最初の条件がfalseと評価された場合でも、2番目の条件を評価する必要はありません。なぜなら、ステートメント全体が真実であることが判明する可能性はないからです。

ステートメントのネストは、オペレーターが短絡評価を実行しなかっifたVB6の古き良き時代の一般的な「最適化」トリックでした。And読みやすさを向上させない限り、Cコードで使用することを想像できる目的はありません。そして正直なところ、これら2つのコードスニペットをパフォーマンスの点で完全に同等にレンダリングしないコンパイラに遭遇した場合は、そのコンパイラを破棄して使用を停止するときが来ました。これは、太陽の下での最も基本的な最適化であり、コンパイラー作成者にとっては「手に負えない成果」です。彼らがこれを正しく理解できない場合、私はあなたのコードの残りの部分で彼らを信頼しません。

しかし、一般的に、この種のこと(これは間違いなく「マイクロ最適化」のカテゴリーに分類されます)について心配することは、より良いコードを書いたり、より良いプログラマーになるのに役立ちません。Stack Overflowで質問するのに多くの時間を浪費し、週に2〜3の同様の質問に同じ回答を投稿する私のようなユーザーの評判に貢献しているだけです。そして、それはあなたがコードを書き、具体的な方法であなたのスキルを向上させることに費やしていない時間です。

于 2011-06-29T12:36:25.797 に答える
2

最新のコンパイラについて誰でも実際に判断できる唯一の方法は、マシン コードを確認することです。

于 2011-06-29T12:29:53.190 に答える
2

違いはないはずです。違いがある場合は、測定できない可能性があります (何百万回も実行しても、決定的な結果は得られません)。

于 2011-06-29T12:31:38.133 に答える
1

10.000.000 回実行するループでこれら 2 つの例をテストすると、次の結果が得られます。

$ time ./test1

real    0m0.045s
user    0m0.044s
sys     0m0.001s

$ time ./test2

real    0m0.045s
user    0m0.043s
sys     0m0.003s

また、式の最初の部分が失敗した場合、2 番目の式は評価されないことに注意してください。これは、最初の例ではあまり明確ではないかもしれません。

また、最初に評価された式が false を返す条件では:

$ time ./test1_1

real    0m0.035s
user    0m0.034s
sys     0m0.001s
$ time ./test2_1

real    0m0.035s
user    0m0.034s
sys     0m0.000s
于 2011-06-29T12:39:41.587 に答える
0

最初のバージョンが常に呼び出すかどうかを考えているtest_some_condition、最初の条件が真の場合にのみ2番目のバージョンが呼び出す場合、答えは、AND演算子が怠惰であり、最初の引数がすでに間違っています。

この規格は、この動作を保証します。これにより、次のように言うことが合法になります。

if (array_size > n && my_array[n] == 1) { ... }

これは、怠惰の保証がなければ壊れたコードになります。

于 2011-06-29T12:34:32.633 に答える
0

複合条件が遅延評価される場合、2つのサンプルは論理的に同等です。つまり、a && bがfalseであることがわかっているb場合は評価されません。aしたがって、違いがあったとしても、それは使用しているコンパイラのアーティファクト(またはバグ)である可能性があり、次のリリースまたはバグ修正で変更される可能性があるため、気にしません。

于 2011-06-29T12:35:50.437 に答える