我想知道在使用逻辑运算符而不是几个if语句时会出现性能差异。我看到了一个很好的link,这也适用于java吗?
答案 0 :(得分: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测试反编译并得到这些结果
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())
答案 1 :(得分:0)
它依赖于实现 - 因此您需要进行基准测试才能确定。
话虽如此,大多数JIT编译器都足够智能,可以非常有效地优化布尔比较,因此您不太可能看到任何差异。
逻辑运算符可能提供实质性优势的唯一区域是您使用它们执行按位计算的情况。这可能非常有效,因为它可能导致无分支代码利用硬件指令。
答案 2 :(得分:0)
两种表单都编译为相同的代码。与其他答案中的建议相反,这不是“优化”,如果不同的编译器做了不同的事情,那将是惊人的。只有一种明智的方法来编译&amp;&amp;那就是把它当作另一个'如果'来对待它。我甚至无法想到一种不合理的方式。