10

Google を使用してこの比較について簡潔な回答を得ることができなかったので、時間のかかる独自の評価を行うのではなく、最初に質問することにしました。

列挙型を使用した switch ステートメントは、if-then-else ステートメントよりも高速に実行されると確信していますが、それが顕著な違いであるかどうかは別の問題です。

誰かが私のためにこれに光を当てることができますか?


迅速な対応に感謝します。今後のプロジェクトでこれを念頭に置きます。

4

6 に答える 6

8

そうです、一般的には、switchステートメントはif/elseチェーンよりも高速に動作するためです。

生成されたバイトコードは、パフォーマンス比較の決定的なソースであるとは限りませんが、それを調べてより良いアイデアを得ることができます。

たとえば、このコード:

class A { 
    enum N { ONE, TWO, THREE }
    void testSwitch( N e ) { 
        switch( e ) { 
            case ONE : x(); break;
            case TWO : x(); break;
            case THREE : x(); break;
        }
    }
    void testIf( Enum e ) { 
        if( e == N.ONE ) { x(); }
        else if( e == N.TWO ) { x(); }
        else if( e == N.THREE ) { x(); }
    }
    void x(){}
}

以下を生成します。

Compiled from "A.java"
class A extends java.lang.Object{
A();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

void testSwitch(A$N);
  Code:
   0:   getstatic   #2; //Field A$1.$SwitchMap$A$N:[I
   3:   aload_1
   4:   invokevirtual   #3; //Method A$N.ordinal:()I
   7:   iaload
   8:   tableswitch{ //1 to 3
        1: 36;
        2: 43;
        3: 50;
        default: 54 }
   36:  aload_0
   37:  invokevirtual   #4; //Method x:()V
   40:  goto    54
   43:  aload_0
   44:  invokevirtual   #4; //Method x:()V
   47:  goto    54
   50:  aload_0
   51:  invokevirtual   #4; //Method x:()V
   54:  return

void testIf(java.lang.Enum);
  Code:
   0:   aload_1
   1:   getstatic   #5; //Field A$N.ONE:LA$N;
   4:   if_acmpne   14
   7:   aload_0
   8:   invokevirtual   #4; //Method x:()V
   11:  goto    39
   14:  aload_1
   15:  getstatic   #6; //Field A$N.TWO:LA$N;
   18:  if_acmpne   28
   21:  aload_0
   22:  invokevirtual   #4; //Method x:()V
   25:  goto    39
   28:  aload_1
   29:  getstatic   #7; //Field A$N.THREE:LA$N;
   32:  if_acmpne   39
   35:  aload_0
   36:  invokevirtual   #4; //Method x:()V
   39:  return

void x();
  Code:
   0:   return

}

どちらの場合もかなり速いようです。

したがって、保守が容易なものを選択してください。

于 2011-02-07T15:22:53.067 に答える
7

あなたが思いつくことができる最も読みやすく、理解しやすいコードに固執してください。この答えをすでに探している間に、パフォーマンスの最適化で得たすべての時間を失ったと確信しています。このようなマイクロ最適化に価値があることはめったになく、コードが必要以上に複雑になる可能性があります。

于 2011-02-07T15:26:33.573 に答える
1

速いかどうかはわかりませんが、どちらも非常に速いと思います。

私の考慮事項は、列挙型のスイッチは、multi-if/elseブロックよりもはるかに読みやすいということです

ただし、breakステートメントの欠落に注意してください!!

于 2011-02-07T15:20:33.050 に答える
1

はい、ほとんどの場合、switch ステートメントは同等の if / else ステートメントのブロックよりも高速に実行されます。これは、コンパイラがより多くの最適化を実行できるためです (通常、switch ブロックはブランチ テーブルにコンパイルされます。条件文。)

また、それらはより読みやすく、より保守しやすいと思います(ただし、私がアドバイスするフォールスルーケースを使用することを除いて!)

顕著に速いかどうかに関しては、何を顕著と定義するかによって異なります。本当に具体的なことを求めていない限り、まったく気付かない可能性がありますが、何よりも読みやすさの利点があるため、私はこの方法で物事を行います (速度の利点をボーナスとして扱います!)

于 2011-02-07T15:25:57.627 に答える
1

これに対する私の答えは、言語構造 X は一般に言語構造 Y よりも高速であるという質問に対するいつもと同じです: 一般的な答えはありません!

Oralce の (以前は Sun の) Hotspot コンパイラ ベースの JVM、プラットフォーム Z の IBM JDK、Linux の OpenJDK など、言語の特定の実装については、特定の回答しかない場合があります。

したがって、あなたの質問に意味のある答えを与える唯一の方法は、適切なベンチマークを行うことです。マイクロ ベンチマークに注意してください。それらは正しいよりも間違っていることが多いです。たとえば、マイクロ ベンチマークを作成しない方法を参照してください。それでも知りたい場合は、こちらで説明されているこの質問フレームワークを使用してください。

そのため、コンテキストでの適用性と読みやすさによって言語機能を選択することをお勧めします。

于 2011-02-07T15:36:00.747 に答える
0

理論的には、switch ステートメントは単一の計算されたジャンプとして最適化できますが、if-then-else チェーンは個別の比較として残す必要があります。ただし、Java が実際にこの最適化を実行するかどうかはわかりません。

いずれにせよ、スイッチは読みやすさと保守性の点で if-then-else チェーンよりも優れているため、可能であればスイッチを使用してください。

于 2011-02-07T15:25:43.187 に答える