6

if ステートメントのベスト プラクティスをいくつか見つけようとしています。何らかの等価性をオンにする必要がある場合、つまり if-else 構文が必要な場合、通常は「等しくない」という条件を記述します。この背後にある理由は、通常、不成功の結果が発生した場合、命令の数とその複雑さが少ないためです。比較プロセスに違いはありますか?等しい (==) と等しくない (!=) の実行時間に違いはありますか?

例 (かなり単純なものですが、一般的な考え方は成り立ちます):

string myString = "weekend";
if(myString != "weekend")
{
    Console.WriteLine("No fun...!");
}
else
{
    //do a bunch of fun stuff with relatively high complexity
    //can expand over many lines of code
}

if-else ステートメントの順序を変更すると、実行時間に違いはありますか?

string myString = "weekend";
if(myString == "weekend")
{        
    //do a bunch of fun stuff with relatively high complexity
    //can expand over many lines of code
}
else
{
    Console.WriteLine("No fun...!");
}
4

6 に答える 6

17

まず、(1) 重要なことを心配する、(2) コードを最もよく見えるように書く、(3) 本当に心配している場合は、それを測定する、という他の回答は正しいです。

とはいえ、意味が保持されている限り、コンパイラはどのような方法でもコードを生成することが許可されており、コンパイラはブール値の「符号」を非常に頻繁に変更して、生成できるようにすることを理解することが重要ですif。より良いコード。コンパイラが C# を IL に変換し、ジッタが IL をマシン コードに変換する場合、ifステートメントは存在しないことに注意してください。ILには「スタックにブールを生成します。ブールがtrue/falseの場合はジャンプします」、またはマシンコードには「レジスタにブールを入れます。レジスタがゼロ/非ゼロの場合はジャンプします」だけです。

あなたが言う時:

if (A())  
    B();
C();

コンパイラは、これらの命令と同等のものを生成できます。

call A()
if last result is false then goto SKIP
call B()
SKIP: call C()

または、次のように簡単に生成できます。

call A()
if last result is true then goto CONSEQUENCE
goto SKIP
CONSEQUENCE: call B()
SKIP: call C()

テストの符号を反転する最初のバージョンは、2 番目のバージョンよりも 1 命令短いため、コードを短くしようとする最適化コンパイラによって生成される可能性が高いことに注意してください。

その精神で、コンパイラは不等式ではなく等号を比較し、テストの符号を反転することを選択できます。そうすることで、より良いコードが生成されます。また同様に、C# コンパイラは、プログラムの意味が変わらない場合や、一方のバージョンが他方より短い場合に、時々変化if (A() <= B())if (!(A() > B())、逆もまた同様です。

私のポイントは、等式から不等式に変更しても、生成されたコードにまったく違いがない可能性があるということです. コンパイラがその仕事をすることを信頼し、他のことを心配してください。

于 2013-06-21T15:15:20.857 に答える
2

発言権があると思っただけで……。

このコードが既に独自の関数に含まれている場合は、チェックを実行してから、残りのコードを実行したくない場合は戻ります。このようなもの:

void PointlessExample(){
    string myString = "weekend";
    if(myString != "weekend")
    {
        Console.WriteLine("No fun...!");
        return;
    }

    //rest of the code
}
于 2013-06-21T15:11:37.863 に答える
1

パフォーマンスに実際の違いはないので (非常にタイトなループに陥った場合にのみ問題になります)、== や != を「標準化」するのではなく、状況。

私は通常、小さいケースを最初に置きます。そうしないと、コードの最後にたくさんのぶら下がりブラケットができてしまうからです。

例えば

if (number != 1337) 
{
    Console.Writeline("Nope")
}
else 
{
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
}

とは対照的に

if (number == 1337) 
{
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
    // Do lots of stuff
}
else 
{
    Console.Writeline("Nope")
}

一部の人々は、アクションを最初に配置し、エッジ ケースを後で配置することを好みます (それは try {} catch {} に似ていると言っています)。したがって、これはベスト プラクティスというよりスタイルの問題です。

多くのものが扱いにくければ、それを関数でラップすることを検討することをお勧めします。つまり、アイテムを配置する順序は関係ありません。

if (number == 1337) 
{
     DoLotsOfStuff();
}
else 
{
    Console.Writeline("Nope")
}
于 2013-06-21T13:53:30.993 に答える