397

私は元パスカルの男で、現在 C# を学んでいます。私の質問は次のとおりです。

以下のコードは、スイッチを作成するよりも高速ですか?

int a = 5;

if (a == 1)
{
    ....
}
else if(a == 2)
{
    ....
}
else if(a == 3)
{
    ....
}
else if(a == 4)
{
    ....
}
else
    ....

そしてスイッチ:

int a = 5;

switch(a)
{
    case 1:
        ...
        break;

    case 2:
        ...
        break;

    case 3:
        ...
        break;

    case 4:
        ...
        break;

    default:
        ...
        break;


}

どちらが速いですか?

私のプログラムは同様の構造を持っているので、私は尋ねています(多くの「else if」ステートメント)。それらをスイッチに変えるべきですか?

4

14 に答える 14

705

ほんの数項目の場合、違いはわずかです。アイテムが多い場合は、間違いなくスイッチを使用する必要があります。

スイッチに 5 つ以上の項目が含まれている場合は、ルックアップ テーブルまたはハッシュ リストを使用して実装されます。これは、前のすべての条件を最初に評価する必要があるため、最後のアイテムに到達するのにはるかに時間がかかる if:s のリストと比較して、すべてのアイテムが同じアクセス時間を取得することを意味します。

于 2009-04-20T11:14:15.947 に答える
184

なんで気にするの?

99.99% の場合、気にする必要はありません。

この種のマイクロ最適化がコードのパフォーマンスに影響を与える可能性はほとんどありません。

また、注意が必要な場合は、コードのパフォーマンス プロファイリングを行う必要があります。その場合、switch ケースと if-else ブロックのパフォーマンスの違いを見つけるのは簡単です。

編集:わかりやすくするために、より明確で保守しやすい設計を実装してください。通常、巨大な switch-case または if-else ブロックに直面した場合の解決策は、ポリモーフィズムを使用することです。変化している動作を見つけてカプセル化します。私は以前、このような巨大で見苦しい switch case コードを処理しなければなりませんでしたが、通常、単純化することはそれほど難しくありません。しかし、ああ、とても満足です。

于 2009-04-20T11:27:23.840 に答える
32

この性能評価を信じて、スイッチケースの方が速いです。

これが結論です。

結果は、switch ステートメントが if-else-if ラダーよりも高速に実行されることを示しています。これは、switch ステートメントを最適化するコンパイラの機能によるものです。if-else-if はしごの場合、コードは、プログラマが決定した順序で各 if ステートメントを処理する必要があります。ただし、switch ステートメント内の各ケースは以前のケースに依存していないため、コンパイラは最速の実行を提供するようにテストの順序を変更できます。

于 2009-04-20T11:11:19.200 に答える
16

考慮すべきもう 1 つの点: これは本当にアプリケーションのボトルネックですか? この種の最適化が本当に必要な場合は、非常にまれです。ほとんどの場合、アルゴリズムとデータ構造を再考することで、高速化を大幅に改善できます。

于 2009-04-20T11:18:41.303 に答える
11

コンパイラはジャンプ テーブルを生成できるため、Switch は通常、if の長いリストよりも高速です。リストが長いほど、switch ステートメントは一連の if ステートメントよりも優れています。

于 2009-04-20T11:11:16.640 に答える
10

私は切り替えが進むべき道だと思います。それはより速く、より良い練習です。

これは、2 つを比較するベンチマーク テストを示すリンクです。

于 2009-04-20T11:10:56.453 に答える
7

テストするのは難しくありません。5 つの数値の間で切り替えまたは ifelse を実行する関数を作成し、その関数に rand(1,5) をスローして、タイミングを計りながら数回ループします。

于 2009-04-20T11:10:07.190 に答える
6

switch通常、可能であれば、コンパイラによってルックアップ テーブルに変換されます。そのため、必要なケースを見つける前に実際にいくつかのケース比較を行うのではなく、任意のケースのルックアップは O(1) です。

そのため、多くの場合、if/else ifチェーンは遅くなります。ただし、ケースがヒットする頻度によっては、違いがない場合があります。

于 2009-04-20T11:13:27.337 に答える
5

よくわかりませんが、使用しているプログラミング言語によって、どちらかの速度が変わると思います。

私は通常、スイッチを使用することを好みます。そうすれば、コードは読みやすくなります。

于 2010-04-04T12:47:32.353 に答える
5

スイッチのパフォーマンス上の利点 (比較的わずかですが注目に値します) よりもはるかに重要なのは、読みやすさの問題です。

私は、一連の if と比較して、意図と純粋な空白が非常に明確な switch ステートメントを見つけました。

于 2009-04-20T11:24:33.333 に答える
5

技術的には、これらはまったく同じ結果を生成するため、ほぼ同じ方法で最適化できるはずです。ただし、コンパイラが ifs よりもジャンプ テーブルを使用して switch ケースを最適化する可能性が高くなります。

ここでは一般的なケースについて話します。5 つのエントリの場合、条件を頻度順に並べると、if に対して実行されるテストの平均数は 2.5 未満になるはずです。非常にタイトなループでない限り、特筆すべきボトルネックはほとんどありません。

于 2009-04-20T11:10:52.087 に答える
3

簡単な答え: Switch ステートメントの方が速い

正しい句を取得するには、平均して 2 つの比較が必要な if ステートメント (サンプル コードを実行する場合)。

switch ステートメントでは、異なるケースの数に関係なく、比較の平均数は 1 になります。コンパイラ/VM は、コンパイル時に可能なオプションの「ルックアップ テーブル」を作成します。

このコードを頻繁に実行する場合、仮想マシンは同様の方法で if ステートメントを最適化できますか?

于 2009-04-20T11:14:58.050 に答える
2

ステートメントは/チェーンswitchと同じ意図を表現していますが、より制限された正式な方法で表現されているため、コードに置かれた条件についてより多くの結論を導き出すことができるため、コンパイラはそれをより適切に最適化できると最初に推測する必要があります (つまり、1 つの状態のみが true である可能性があり、比較される値はプリミティブ型であるなどです) 実行時のパフォーマンスについて 2 つの類似した言語構造を比較する場合、これは非常に安全な一般的な真実です。ifelse

于 2009-04-20T19:25:51.163 に答える
2

http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.switch%28VS.71%29.aspxを参照して ください。

switchステートメントは基本的にルックアップテーブルであり、既知のオプションがあり、ifステートメントはブール型に似ています。私によると、スイッチとif-elseは同じですが、ロジックスイッチの場合はより効果的です。if-else は読書でも理解するのに役立ちます。

于 2012-09-29T08:24:12.120 に答える