Google を使用してこの比較について簡潔な回答を得ることができなかったので、時間のかかる独自の評価を行うのではなく、最初に質問することにしました。
列挙型を使用した switch ステートメントは、if-then-else ステートメントよりも高速に実行されると確信していますが、それが顕著な違いであるかどうかは別の問題です。
誰かが私のためにこれに光を当てることができますか?
迅速な対応に感謝します。今後のプロジェクトでこれを念頭に置きます。
Google を使用してこの比較について簡潔な回答を得ることができなかったので、時間のかかる独自の評価を行うのではなく、最初に質問することにしました。
列挙型を使用した switch ステートメントは、if-then-else ステートメントよりも高速に実行されると確信していますが、それが顕著な違いであるかどうかは別の問題です。
誰かが私のためにこれに光を当てることができますか?
迅速な対応に感謝します。今後のプロジェクトでこれを念頭に置きます。
そうです、一般的には、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
}
どちらの場合もかなり速いようです。
したがって、保守が容易なものを選択してください。
あなたが思いつくことができる最も読みやすく、理解しやすいコードに固執してください。この答えをすでに探している間に、パフォーマンスの最適化で得たすべての時間を失ったと確信しています。このようなマイクロ最適化に価値があることはめったになく、コードが必要以上に複雑になる可能性があります。
速いかどうかはわかりませんが、どちらも非常に速いと思います。
私の考慮事項は、列挙型のスイッチは、multi-if/elseブロックよりもはるかに読みやすいということです
ただし、breakステートメントの欠落に注意してください!!
はい、ほとんどの場合、switch ステートメントは同等の if / else ステートメントのブロックよりも高速に実行されます。これは、コンパイラがより多くの最適化を実行できるためです (通常、switch ブロックはブランチ テーブルにコンパイルされます。条件文。)
また、それらはより読みやすく、より保守しやすいと思います(ただし、私がアドバイスするフォールスルーケースを使用することを除いて!)
顕著に速いかどうかに関しては、何を顕著と定義するかによって異なります。本当に具体的なことを求めていない限り、まったく気付かない可能性がありますが、何よりも読みやすさの利点があるため、私はこの方法で物事を行います (速度の利点をボーナスとして扱います!)
これに対する私の答えは、言語構造 X は一般に言語構造 Y よりも高速であるという質問に対するいつもと同じです: 一般的な答えはありません!
Oralce の (以前は Sun の) Hotspot コンパイラ ベースの JVM、プラットフォーム Z の IBM JDK、Linux の OpenJDK など、言語の特定の実装については、特定の回答しかない場合があります。
したがって、あなたの質問に意味のある答えを与える唯一の方法は、適切なベンチマークを行うことです。マイクロ ベンチマークに注意してください。それらは正しいよりも間違っていることが多いです。たとえば、マイクロ ベンチマークを作成しない方法を参照してください。それでも知りたい場合は、こちらで説明されているこの質問フレームワークを使用してください。
そのため、コンテキストでの適用性と読みやすさによって言語機能を選択することをお勧めします。
理論的には、switch ステートメントは単一の計算されたジャンプとして最適化できますが、if-then-else チェーンは個別の比較として残す必要があります。ただし、Java が実際にこの最適化を実行するかどうかはわかりません。
いずれにせよ、スイッチは読みやすさと保守性の点で if-then-else チェーンよりも優れているため、可能であればスイッチを使用してください。