2015-03-13 96 views
0

我用下面的简单的逻辑来回答question像这样的:如果(a && b)比(a)如果(b)需要更多时间?

1: if(a)  // 1 operation 
2: if (b)  // 1 operation 

1: if(a && b) // 1, 1(&&), 1 => 3 operations. 

所以,2个操作对3,但在第一实施例的编译器需要调用另一个指令被执行。

这个逻辑是正确的吗? 它依赖于编译器吗? 调用一个空指令是否会造成编译器一些明显的时间?

This也讨论了同样的问题,但没有考虑这个逻辑。 请帮助我们澄清此问题。

+0

我不认为他们是不同的,性能将取决于使用情况。如果在第二种类型之前使用第一种类型,那么第一种类型需要更多时间,反之亦然。基本上都是一样的。 – Prashant 2015-03-13 13:27:32

+1

在&&运算符的情况下,如果a通过,则b将不会被评估。它的短路。 – muasif80 2015-03-13 13:28:44

+0

等等...只是为了检查。我们在谈论运行速度还是编译速度?你已经使用了诸如“*是否调用空指令......花费**编译器**一些通知时间”等短语,但我不禁想到你正在讨论运行时。 – 2015-03-13 13:50:12

回答

4

有两种方法来回答这样的问题精确

1)看IL代码(和/或)aassembly代码产生和计数执行该代码所需的CPU周期(提示:这不适合初学者)

2.)构建一个小型测试程序,它可以在很长的时间内执行两种变体,使用StopWatch()创建一个可观的和可读的定时输出,运行几次。

3)猜测你的想法编译器的优化步骤是可以做,什么该软件将做,与他人小时争论

+0

但最终都是一样的! – Prashant 2015-03-13 13:33:03

+0

如果你只是解释如何获得答案,我不确定它是否作为答案。尽管如此,这是有趣的信息。 – 2015-03-13 13:44:49

+2

@邓肯给一个男人一条鱼,你喂他一天;教导一个男人去钓鱼,并且你一辈子喂他 – DrKoch 2015-03-13 17:40:16

-1

有思考你的问题2点的方法:

  1. Java语言定义

    • 语言定义了第二示例将使用短路执行这意味着的情况下的if语句将包含任何代码,所述第二实例可以执行得更快
  2. JVM的优化

    • JVM运行时将删除死代码块是否它可以证明它们没有任何副作用
+0

你的第一个论证对我来说没有意义。在第一个例子中,代码的结构隐含了短路的执行。除非你能解释你认为我们在这里有什么死代码块,否则你的第二个参数没有什么意义。 – 2015-03-13 13:48:44

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。结果可能会与其他编译器不同,但我怀疑它们不适合这种情况。

相关问题