複数のifステートメントの代わりに論理演算子を使用していると、パフォーマンスに違いがあるのではないかと思っていました。素敵なリンクを見ましたが、これはJavaにも当てはまりますか?
質問する
1340 次
3 に答える
4
次のようなクラスを作成しました
class Test{
static java.util.Random r=new java.util.Random();
boolean test(){
return r.nextBoolean();
}
void test1(){
if (test() && test() && test())
System.out.println("3x yes");
}
void test2(){
if (test())
if (test())
if (test())
System.out.println("3x yes");
}
}
コンパイルしてからjavap -c Testで逆コンパイルし、これらの結果を得ました
class Test {
static java.util.Random r;
Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":
()V
4: return
boolean test();
Code:
0: getstatic #2 // Field r:Ljava/util/Random;
3: invokevirtual #3 // Method java/util/Random.nextBoole
an:()Z
6: ireturn
void test1();
Code:
0: aload_0
1: invokevirtual #4 // Method test:()Z
4: ifeq 29
7: aload_0
8: invokevirtual #4 // Method test:()Z
11: ifeq 29
14: aload_0
15: invokevirtual #4 // Method test:()Z
18: ifeq 29
21: getstatic #5 // Field java/lang/System.out:Ljava/
io/PrintStream;
24: ldc #6 // String 3x yes
26: invokevirtual #7 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
29: return
void test2();
Code:
0: aload_0
1: invokevirtual #4 // Method test:()Z
4: ifeq 29
7: aload_0
8: invokevirtual #4 // Method test:()Z
11: ifeq 29
14: aload_0
15: invokevirtual #4 // Method test:()Z
18: ifeq 29
21: getstatic #5 // Field java/lang/System.out:Ljava/
io/PrintStream;
24: ldc #6 // String 3x yes
26: invokevirtual #7 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
29: return
static {};
Code:
0: new #8 // class java/util/Random
3: dup
4: invokespecial #9 // Method java/util/Random."<init>":
()V
7: putstatic #2 // Field r:Ljava/util/Random;
10: return
}
ご覧のとおり、test1
とのバイトコードtest2
は同じなので、使用に違いはありません。
if (test() && test() && test())
また
if (test())
if (test())
if (test())
于 2012-07-26T21:00:58.947 に答える
0
どちらの形式も同じコードにコンパイルされます。他の回答の提案に反して、これは「最適化」ではなく、異なるコンパイラが異なることをしたとしたら驚くべきことです。&& をコンパイルする賢明な方法は 1 つしかなく、それはそれを別の 'if' と同じように扱うことです。無意味な方法も思いつきません。
于 2012-07-27T01:37:45.673 に答える
0
これは実装に依存するため、確実にベンチマークする必要があります。
そうは言っても、ほとんどの JIT コンパイラはブール値の比較を非常に効果的に最適化できるほどスマートであるため、違いが見られる可能性はほとんどありません。
論理演算子が実質的な利点を提供する可能性が高い唯一の領域は、それらを使用してビットごとの計算を実行する場合です。これは、ハードウェア命令を悪用するブランチレス コードになる可能性があるため、非常に効率的です。
于 2012-07-26T20:57:40.687 に答える