2

私がこのコードを持っている場合:

if (isFoo() && isBar())
{
    ...
}

プログラムは最初の条件を計算し、次に2番目の条件を計算してから、以下のブロックを通過するかスキップするかを決定します。

ただし、次のような条件をネストすると、次のようになります。

if (isFoo())
    if(isBar())
    {
        ...
    }

これで、最初の条件をチェックし、それがfalseの場合、2番目の条件を気にしません。

2番目の条件(関数である)が時間のかかるメモリを消費する豚である場合は、ネストする方がよいようです。

これは本当ですか?私はこれまでこのようなコードを見たことがなく、最初の例の後で仮定を立てましたが、IMOはそれが可能性が高いです。

4

6 に答える 6

3

プログラミング言語によって異なります。

現代/人気のある言語のほとんどは短絡評価をサポートしています。つまり、プログラムは式全体を評価しませんが、式全体の結果を取得した直後に評価を停止します(他の言語はすでに例を示しています)。

しかし、例外があります

短絡評価をサポートしていない私が知っている2つの言語は、Microsoft VB(6)とVB.NETです。

VB6はそれをまったくサポートしていないので、ここではIf一般的な最適化手法の場合はネストします。さらに次のような表現で

If Not rs Is Nothing And Not rs.EOF

ネストを使用しないとIf、が実行中に実行エラーが発生しrsますNothing

VB.NET短絡評価をサポートする2つの新しい論理演算子を導入しましAndAlsoた。OrElse

標準VB.NET AndおよびOr演算子は、新規開発者の場合のバグの一般的な原因である短絡評価をサポートしていません。

最適化

どちらの場合も(言語サポートであり、短絡評価ではありません)、最初に評価するのが速い順に式をチェックできます。

したがって、(ユーザーが女性で、キーが偶数でログインしている場合はDBをチェックインする)の代わりに:

if (db.getUserSex() == FEMALE && userKey % 2 == 0 && userKey % 2 && isUserLogged)

使用(ログインしているかどうか(ブール値)、偶数キー(算術演算子)を使用してチェックし、最後にDBで性別をチェックします):

if (isUserLogged && userKey % 2 == 0 && db.getUserSex() == FEMALE)
于 2012-12-30T09:11:27.427 に答える
2

C#/ C ++および他の多くの言語では、AND実際には2つの論理演算子が&あり&&ます。

&オペレーターは両方の条件を評価します

&&演算子は最初にのみ評価し、等しい場合はFALSE、式の2番目の部分をスキップします。

OR同じことが論理演算子にも当てはまります。2つの演算子があります:|||

|オペレーターは両方の条件を評価します

||演算子は最初にのみ評価し、等しい場合はTRUE、式の2番目の部分をスキップします。

したがって、質問に答えると、あなたの例では、を使用しています。これは、2つの&&ネストされたものとして動作します。if

[編集]:わかりました、|の使用例を見つけるのはそれほど簡単ではありません そして&、個人的に私は最短コードのコンテストでそれらを使用しました))これはそれらが本当に役立つところです(&&と||より短いからではありません)。次の例も検討してください。

static bool LaunchFirstRocket()
{
    // Launching rocket if all is ok return true, or return false if we failed to launch it.
}

static bool LaunchSecondRocket()
{
    // Launching rocket if all is ok return true, or return false if we failed to launch it.
} 

static void Main(string[] args)
{
    if (LaunchFirstRocket() & LaunchSecondRocket())
    {
        Console.WriteLine("Both rockets have launched successfully!");
    }
}

ここでは、最初のメソッドの結果に関係なく、両方のメソッドを強制的に実行します。最初のロケットが失敗した場合でも、2番目のロケットを打ち上げたいと考えています。これが私たちの論理です。はい、そのようなコードを書く方法は他にもたくさんありますが、これは教育目的の単なる例です。

于 2012-12-30T08:48:40.983 に答える
1

ほとんどのコンパイラがこの最適化を行ってくれると思います。&&の最初の条件が偽の場合、2番目の条件は実行されません。

于 2012-12-30T08:39:10.707 に答える
1

プログラムは最初の条件を計算し、次に2番目の条件を計算します。

いいえ、ほとんどの現代言語(C、C ++など)ではありません。最初の条件がfalseの場合、AND式の値はfalse以外にはなり得ないことがわかっているため、2番目の部分は評価されません。これらの2つの言語では、標準でこの最適化が明示的に定義されています(「短絡評価」と呼ばれます)。

于 2012-12-30T08:40:46.987 に答える
1

場合によります。他の人が指摘しているように、短絡評価のあるコンパイル言語(CやC ++など)では、両方のバージョンがまったく同じコードにコンパイルされる可能性があります。

Perlなどの一部のインタプリタ言語では、コードブロックの入力にわずかなオーバーヘッドがあるため、実際には2番目のバージョンは最初のバージョンよりもわずかに遅い場合があります。たとえば、この人工的なベンチマークは、違いを明確に示しています。

use Benchmark ':all';
my $count = shift || 10_000_000;
our ($foo, $bar, $baz) = (1, 1, 1);
timethese( $count, {
    'and'    => 'if ($foo && $bar) { $baz++; }',
    'nested' => 'if ($foo) { if ($bar) { $baz++; } }',
});

出力:

Benchmark: timing 10000000 iterations of and, nested...
       and:  2 wallclock secs ( 2.41 usr +  0.00 sys =  2.41 CPU) @ 4149377.59/s (n=10000000)
    nested:  4 wallclock secs ( 3.54 usr +  0.00 sys =  3.54 CPU) @ 2824858.76/s (n=10000000)

もちろん、実際には、特に通訳言語を最初に使用する一般的なオーバーヘッドと比較すると、違いは完全に重要ではない可能性があります。

于 2012-12-30T08:58:48.997 に答える
0

現代語はすべて、AND句を省略します。したがって、あなたの例では、isFoo()がfalseの場合、isBar()をチェックすることすらなく、ifステートメントを終了します。

于 2012-12-30T08:39:35.100 に答える