2013-01-11 53 views
1

假設我們有一個盒裝雙變量,foo,我們希望將它的值乘以2並將其存儲在另一個盒裝雙變量bar中。從以下方法,將盒裝雙倍乘以2的最有效方法是?

方法一:

Double bar = foo * 2; 

和,

方法二:

Double bar = Double.valueOf(foo.doubleValue() * 2); 

哪一個更優選考慮效率,可讀性和等等。?還是差異如此微不足道,這些方法實際上是相同的?

+3

從可讀性,你可以回答自己的問題,從效率,我asume依賴於VM – AlexWien

+0

執行這兩個應該是等價的,如自動裝箱被編譯成以'valueOf' –

+1

@IanRoberts呼叫:雖然經常聲稱,但實際上並不需要。 JLS僅指定將不是NaN的原始雙p轉換爲類的類型和類型Double的引用r,從而r.doubleValue()的計算結果爲p「。編譯器也可以使用例如「新Double(p)」而不是「Double.valueOf(p)」,仍然堅持JLS。 – jarnbjo

回答

4

第一個。它具有更好的可讀性,並保留了現場所有的裝箱/拆箱操作。

不要考慮如乘以2等簡單操作的效率。

...或長的答案

有兩種方法:

void method1() { 
    Double foo = 1.0; 
    Double bar = foo * 2; 
} 

void method2() { 
    Double foo = 1.0; 
    Double bar = Double.valueOf(foo.doubleValue() * 2); 
} 

編譯javac,並期待字節碼指令與javap

void method1(); 
    Code: 
     0: dconst_1 
     1: invokestatic #2     // Method java/lang/Double.valueOf:(D)Ljava/lang/Double; 
     4: astore_1 
     5: aload_1 
     6: invokevirtual #3     // Method java/lang/Double.doubleValue:()D 
     9: ldc2_w  #4     // double 2.0d 
    12: dmul 
    13: invokestatic #2     // Method java/lang/Double.valueOf:(D)Ljava/lang/Double; 
    16: astore_2 
    17: return 

void method2(); 
    Code: 
     0: dconst_1 
     1: invokestatic #2     // Method java/lang/Double.valueOf:(D)Ljava/lang/Double; 
     4: astore_1 
     5: aload_1 
     6: invokevirtual #3     // Method java/lang/Double.doubleValue:()D 
     9: ldc2_w  #4     // double 2.0d 
    12: dmul 
    13: invokestatic #2     // Method java/lang/Double.valueOf:(D)Ljava/lang/Double; 
    16: astore_2 
    17: return 

你能看出其中的區別?

+1

正如我在對問題的評論中指出的那樣,拳擊轉換是特定於實現的。如果您在編譯器的輸出中看不到差異,並不意味着我的編譯器執行相同的操作。 – jarnbjo

+0

@jarnbjo表示同意 – mishadoff

3

我認爲無論您如何優化它,java都會使此版本Double bar = foo * 2;至少與您的解決方案一樣優化。試圖獲得這樣的表現通常是徒勞的。

+0

我知道這種微型優化是徒勞的。我只是出於好奇而問! – mre

4

方法一更好。

  • 它可以由人來閱讀
  • 所有其他條件相同,個字符不止字符
  • 編譯器可能會刪除任何性能差異較好。
+0

對第1點和第3點不能同意。這些可能是在進行任何優化之前應該首先進入您的腦海的第一件事。 –