假設我們有一個盒裝雙變量,foo
,我們希望將它的值乘以2
並將其存儲在另一個盒裝雙變量bar
中。從以下方法,將盒裝雙倍乘以2的最有效方法是?
方法一:
Double bar = foo * 2;
和,
方法二:
Double bar = Double.valueOf(foo.doubleValue() * 2);
哪一個更優選考慮效率,可讀性和等等。?還是差異如此微不足道,這些方法實際上是相同的?
假設我們有一個盒裝雙變量,foo
,我們希望將它的值乘以2
並將其存儲在另一個盒裝雙變量bar
中。從以下方法,將盒裝雙倍乘以2的最有效方法是?
方法一:
Double bar = foo * 2;
和,
方法二:
Double bar = Double.valueOf(foo.doubleValue() * 2);
哪一個更優選考慮效率,可讀性和等等。?還是差異如此微不足道,這些方法實際上是相同的?
第一個。它具有更好的可讀性,並保留了現場所有的裝箱/拆箱操作。
不要考慮如乘以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
你能看出其中的區別?
我認爲無論您如何優化它,java都會使此版本Double bar = foo * 2;
至少與您的解決方案一樣優化。試圖獲得這樣的表現通常是徒勞的。
我知道這種微型優化是徒勞的。我只是出於好奇而問! – mre
方法一更好。
對第1點和第3點不能同意。這些可能是在進行任何優化之前應該首先進入您的腦海的第一件事。 –
從可讀性,你可以回答自己的問題,從效率,我asume依賴於VM – AlexWien
執行這兩個應該是等價的,如自動裝箱被編譯成以'valueOf' –
@IanRoberts呼叫:雖然經常聲稱,但實際上並不需要。 JLS僅指定將不是NaN的原始雙p轉換爲類的類型和類型Double的引用r,從而r.doubleValue()的計算結果爲p「。編譯器也可以使用例如「新Double(p)」而不是「Double.valueOf(p)」,仍然堅持JLS。 – jarnbjo