62

私はこれをしばらく前から疑問に思っていました。私はハードコアプログラマーではなく、主に小さなPythonスクリプトであり、分子動力学シミュレーションをいくつか作成しました。本当の質問の場合:switchステートメントのポイントは何ですか?if-elseステートメントだけを使用できないのはなぜですか?

あなたの答えをありがとう、そしてこれが前に尋ねられたならば、私にリンクを指摘してください。

編集

S.Lottは、これはIf / Elsevs.Switchの質問と重複している可能性があると指摘しています。閉じたい場合はそうしてください。さらなる議論のためにそれを開いたままにしておきます。

4

8 に答える 8

91

switchコンストラクトは、より簡単にジャンプ (またはブランチ) テーブルに変換されます。これにより、case ラベルが近接している場合に、 switch ステートメントをif-elseよりもはるかに効率的にすることができます。アイデアは、一連のジャンプ命令をメモリに順番に配置し、その値をプログラム カウンターに追加することです。これにより、一連の比較命令が加算操作に置き換えられます。

以下は、非常に単純化された疑似アセンブリの例です。まず、if-else バージョン:

    // C version
    if (1 == value)
        function1();
    else if (2 == value)
        function2();
    else if (3 == value)
        function3();

    // assembly version
    compare value, 1
    jump if zero label1
    compare value, 2
    jump if zero label2
    compare value, 3
    jump if zero label3
label1:
    call function1
label2:
    call function2
label3:
    call function3

次はスイッチ版です。

    // C version
    switch (value) {
    case 1: function1(); break;
    case 2: function2(); break;
    case 3: function3(); break;
    }

    // assembly version
    add program_counter, value
    call function1
    call function2
    call function3

結果のアセンブリ コードがはるかにコンパクトになっていることがわかります。1、2、および 3 以外の値を処理するには、何らかの方法で値を変換する必要があることに注意してください。ただし、これは概念を説明するものです。

于 2009-01-16T02:15:33.993 に答える
24

スイッチはコンパイルrによって最適化することができます-あなたはより速いコードを得るでしょう。
また、列挙可能なタイプを扱うときは、よりエレガントであることがわかります。

switchステートメントを要約すると、パフォーマンスとコードの優雅さが得られます:)

ここにいくつかの便利なリンクがあります:

于 2009-01-16T02:05:19.817 に答える
8

表現力を高めるために、switch/case ステートメントを使用すると、複数のケースをグループ化できます。次に例を示します。

case 1,2,3: do(this); break;
case 4,5,6: do(that); break;

パフォーマンスのために、コンパイラは switch ステートメントをジャンプ テーブルに最適化できる場合があります。

于 2009-01-16T02:06:40.920 に答える
7

この種の低レベルの最適化は、通常は重要ではなく、おそらくコンパイラごとに異なるため、無視しています。

主な違いは読みやすさだと思います。if/else は非常に柔軟ですが、スイッチが表示されると、すべてのテストが同じ式に対して行われていることがすぐにわかります。

于 2009-01-16T02:45:58.987 に答える
4

他の言及されたコードの読みやすさと.NETでの最適化に加えて、列挙型などをオンにする機能も取得します

enum Color { Red, Green, Blue }; 

Color c = Color.Red;

switch (c) // Switch on the enum

{

// no casting and no need to understand what int value it is

case Color.Red:    break;
case Color.Green:  break;
case Color.Blue:   break;

}
于 2009-01-16T02:15:25.677 に答える
3

いくつかのケースを通過する機能 (故意に break ステートメントを除外する) は便利であり、数人がすでに言っているように、高速でもあります。ただし、おそらく最も重要で最も重要でない考慮事項は、if/else よりもきれいなコードになるということです。:)

于 2009-01-16T02:15:59.717 に答える
2

一部のコンパイラでは、スイッチを「より適切に」最適化できます。特定の言語で switch ステートメントを使用すると、落とし穴があります。Java では、スイッチは文字列を処理できず、VB2005 では、switch ステートメントはラジオ ボタンでは機能しません。
Switch はより高速で読みやすく、If-Then はより汎用的で、より多くの場所で機能します。

于 2009-01-16T02:10:07.433 に答える
-1

ケースの値が定数であり、動的またはその他の方法で導出されたものではない場合、およびケースの数がルックアップ テーブルへのハッシュを計算する時間よりも大幅に大きい場合にのみ、時間の切り替えが高速になります。

Chrome の V8 エンジンを含むほとんどのエンジンで実行するためにアセンブリにコンパイルされる Javascript の適切な例は、一般的なケースでの switch ステートメントの実行が 30% ~ 60% 遅いことです: http://jsperf.com/switch-if -他/20

于 2013-03-29T22:15:11.743 に答える