我使用以下简单的逻辑来回答像这样的question:
1: if(a) // 1 operation
2: if (b) // 1 operation
和
1: if(a && b) // 1, 1(&&), 1 => 3 operations.
所以,2个操作与3个,但在第一个例子中,编译器需要调用另一个指令来执行。
这个逻辑是真的吗?
它取决于编译器吗?
调用像;
这样的空指令会花费编译器一些值得注意的时间吗?
This 也讨论了同样的问题,但没有考虑这个逻辑。 请帮助我们澄清这个问题。
答案 0 :(得分:4)
有两种方法可以回答 这样的问题:
1。)查看IL代码(和/或)组装代码生成并计算执行此代码所需的CPU周期(提示:这不适合初学者)
2.。)构建一个小型测试程序,大量执行这两个变体,使用StopWatch()创建一个有意义且可读的定时输出,运行几次。
3。)推测您认为编译器的优化步骤能够做什么以及该软件将做什么,与其他人争论几个小时
答案 1 :(得分:2)
我假设编译器会为您的两种情况生成相同的字节代码。所以我用两个不同的源文件测试了它:
public class Test1 {
public static void main(String[] args) {
if (args[0].equals("a"))
if (args[1].equals("b"))
System.out.println("Foo");
}
}
和...
public class Test2 {
public static void main(String[] args) {
if (args[0].equals("a") && args[1].equals("b"))
System.out.println("Foo");
}
}
用javap -c Test1
等检查字节代码,结果完全相同:
public static void main(java.lang.String[]); Code: 0: aload_0 1: iconst_0 2: aaload 3: ldc #2 // String a 5: invokevirtual #3 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 8: ifeq 30 11: aload_0 12: iconst_1 13: aaload 14: ldc #4 // String b 16: invokevirtual #3 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 19: ifeq 30 22: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream; 25: ldc #6 // String Foo 27: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 30: return
因此,表现将是相同的。虽然我欢迎评论,如果有人能想到一个产生不同字节码的例子。
我的结果是使用Java 1.7中的Oracle javac
。结果可能与其他编译器不同,尽管我怀疑他们不会成为这种情况。
答案 2 :(得分:-1)
有两种方法可以考虑你的问题:
Java语言定义
if
语句将包含任何代码的情况下,第二个示例可以执行得更快 JVM优化