2015-03-13 63 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。結果可能會與其他編譯器不同,但我懷疑它們不適合這種情況。

相關問題