選項1:將整數轉換爲字符串 - 從性能和內存的角度使用字符串文字或基元?
String newStr = someStr + 3 + "]";
選項2:
String newStr = someStr + "3" + "]";
哪個選項是關於性能,內存和一般的做法更好? 什麼是我可以用來測量我的代碼和它的性能(除了測量開始時間和結束時間,並計算差異)的內存使用的一些推薦的工具/方式是什麼
選項1:將整數轉換爲字符串 - 從性能和內存的角度使用字符串文字或基元?
String newStr = someStr + 3 + "]";
選項2:
String newStr = someStr + "3" + "]";
哪個選項是關於性能,內存和一般的做法更好? 什麼是我可以用來測量我的代碼和它的性能(除了測量開始時間和結束時間,並計算差異)的內存使用的一些推薦的工具/方式是什麼
這兩者之間不會有任何明顯的差異。使用你發現的最具邏輯性和可讀性。我會用
String newStr = someStr + "3]";
我會建議Jprofiler是一個偉大的Java應用程序分析工具,幫助我找到很多的內存問題。
我不認爲選項1和2在內存使用方面有很大差異,特別是對於桌面應用程序。
感謝您的工具建議! – user1739658 2013-02-08 23:46:32
沒問題!請接受最有用的答案;-) – Simon 2013-02-09 00:17:15
第一個將成爲:
StringBuilder sb = new StringBuilder (String.valueOf (someStr));
sb.append (3);
sb.append ("]");
String newStr = sb.toString();
第二個將成爲:
StringBuilder sb = new StringBuilder (String.valueOf (someStr));
sb.append ("3");
sb.append ("]");
String newStr = sb.toString();
這裏是拆解:
public String foo (String someStr)
{
String newStr = someStr + 3 + "]";
return newStr;
}
public String bar (String someStr)
{
String newStr = someStr + "3" + "]";
return newStr;
}
public java.lang.String foo(java.lang.String);
Code:
0: new #16 // class java/lang/StringBuilder
3: dup
4: aload_1
5: invokestatic #18 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
8: invokespecial #24 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
11: iconst_3
12: invokevirtual #27 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
15: ldc #31 // String ]
17: invokevirtual #33 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: invokevirtual #36 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: astore_2
24: aload_2
25: areturn
public java.lang.String bar(java.lang.String);
Code:
0: new #16 // class java/lang/StringBuilder
3: dup
4: aload_1
5: invokestatic #18 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
8: invokespecial #24 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
11: ldc #44 // String 3
13: invokevirtual #33 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: ldc #31 // String ]
18: invokevirtual #33 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #36 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_2
25: aload_2
26: areturn
第一個將追加'3'(裝箱到整數3),然後追加']'。第二個追加'3]' – 2013-02-08 23:15:40
+1。我不知道爲什麼,但我的眼睛在第二種情況下看到了不變,但不是第一種。 – 2013-02-08 23:15:52
糟糕。 Steve Kuo是對的。'String s =「hello」+ 3 +「]」'雖然創建了一個String'「hello3]」''。奇怪的是,編譯器無法優化這種情況。 +1還是因爲我學到了一些東西。 – 2013-02-08 23:21:41
假設someString是恆定的,兩者都是常量表達式將在編譯時進行評估。它們將導致相同的類文件和運行時行爲。
來源:Java Language Specification寫道:
編譯時常量表達式是表示原始類型或字符串的一個值,該值不會突然完成並只使用由以下的表達式:
原語類型和類型字符串的文字(§3.10.1,§3.10.2,§3.10.3,§3.10.4,§3.10.5)添加劑OPE的
字面rators
+
和-
(§15.18)...
編譯時String類型的常量表達式總是 「實習」,以便共享獨特實例,使用該方法的String.intern。
如果someString不是恆定的,最現代的編譯器將使用StringBuilder,這是明確permitted由Java語言規範:
字符串連接的結果是一個String對象的引用是兩個操作數字符串的連接。左側操作數的字符位於新創建的字符串中右側操作數的字符之前。
除非表達式是編譯時常量表達式(§15.28),否則String對象是新創建的(§12.5)。
實現可以選擇在一個步驟中執行轉換和連接以避免創建並丟棄中間String對象。爲了提高重複字符串連接的性能,Java編譯器可以使用StringBuffer類或類似技術來減少通過評估表達式創建的中間String對象的數量。
對於基元類型,實現還可以通過直接從基元類型轉換爲字符串來優化封裝器對象的創建。
這非常有幫助。非常感謝你! – user1739658 2013-02-08 23:37:36
每當您將字符串,每個級聯,創建字符串的一個新的副本和兩個字符串複製過來,每次一個字符。這導致O的時間複雜度(McDowell)。
如果你想提高性能,使用
StringBuilder
它的一個構造函數的語法如下:(字符的可變序列記住字符串immmutable)
public StringBuilder(int size); //Contains no character. Initial capacity of 'size'.
的StringBuilder有助於解決此只需創建一個所有字符串的可調整大小的數組即可解決問題只有在必要時纔將它們複製回字符串(McDowell)。
StringBuilder str = new StringBuilder(0);
str.append(someStr);
str.append(3);
str.append("]");
參考:
道爾,蓋爾Laakmann。破解編碼採訪,第6版。打印。
「Stringbuilder(Java Platform SE 8)」。 Docs.oracle.com。 N.p.,2016.網站。 2016年6月4日。
兩者都沒有什麼區別。 – Smit 2013-02-08 23:10:20
@Smit:編譯器將使用StringBuilder來進行字符串連接 – jlordo 2013-02-08 23:13:24
@Smit:使用StringBuilder會導致與問題中的代碼相同的字節碼,或者更糟糕。 – 2013-02-08 23:13:45