[英]Best practices/performance: mixing StringBuilder.append with String.concat
我試圖了解最佳做法是什么,以及為什么要針對不同情況連接字符串文字和變量。 例如,如果我有這樣的代碼
StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
.append(B_String).append("CCCCCCCCCCC").append(D_String)
.append("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
.append("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
這是這樣做的方法嗎? 從這篇文章中,我注意到 Strings 上的+
運算符創建了一個新的 StringBuilder 實例,連接操作數,並返回一個 String 轉換,這似乎比調用.append()
要多得多; 所以如果那是真的,那就不可能了。 但是String.concat()
呢? 每次連接都使用.append()
是否合適? 或者只是對於變量,文字對於 append 和.concat()
是可以的嗎?
StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
.append(B_String.concat("CCCCCCCCCCC")).append(D_String
.concat("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
.concat("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
處理這些情況的最佳實踐和表現的一般規則是什么? 我對+
的假設是否正確,它真的不應該被使用嗎?
+
運營商String s = s1 + s2
在幕后,這被翻譯成:
String s = new StringBuilder(s1).append(s2).toString();
想象一下如果你在這里有s1 + s2
會增加多少額外的工作:
stringBuilder.append(s1 + s2)
代替:
stringBuilder.append(s1).append(s2)
+
的多個字符串值得注意的是:
String s = s1 + s2 + s3 + ... +sN
被翻譯成:
String s = new StringBuilder(s1).append(s2).append(s3)...apend(sN).toString();
concat()
String s = s1.concat(s2);
String
創建可以同時容納s1
和s2
的char[]
數組。 將s1
和s2
的內容復制到這個新數組。 實際上比+
運算符需要更少的工作。
StringBuilder.append()
維護一個在需要時增長的內部char[]
數組。 如果內部字符足夠大,則不會創建額外的char[]
。
stringBuilder.append(s1.concat(s2))
也表現不佳,因為s1.concat(s2)
創建了一個額外的char[]
數組並將s1
和s2
復制到它只是為了將新數組內容復制到內部StringBuilder
char[]
。
話雖如此,您應該一直使用append()
和 append 原始字符串(您的第一個代碼片段是正確的)。
編譯器優化 + 連接。
所以
int a = 1;
String s = "Hello " + a;
被轉化為
new StringBuilder().append("Hello ").append(1).toString();
這里有一個很好的主題,解釋了為什么應該使用 + 運算符。
優化由編譯器自動完成。
Java2 編譯器將自動轉換以下內容:
String s = s1 + s2;
到
String s = (new StringBuffer()).append(s1).append(s2).toString();
您應該始終使用append
。
concat
創建一個新的 String 所以它很像+
我認為。
如果您將+
與 2 個最終字符串連接或使用,則concat
可以進行優化,因此在這種情況下與 append 相同。
如果您正好連接兩個字符串,請使用 String.concat(通過創建一個適合兩個字符串的新字符數組並將兩個字符串的字符 arrays 復制到其中來創建一個新字符串)。
如果您在一行中連接多個(超過兩個)字符串,請使用 + 或 StringBuilder.append,這無關緊要,因為編譯器會將 + 轉換為 StringBuilder.append。 這對多個字符串很有用,因為它維護了一個根據需要增長的字符數組。
如果您在多行中連接多個字符串,請創建一個 StringBuilder 並使用追加方法。 最后,當您完成將字符串附加到 StringBuilder 后,使用它的 .toString() 方法從中創建一個字符串。 對於多行連接,這比第二種方法更快,因為第二種方法會在每一行上創建一個新的 StringBuilder,即 append 字符串,然后轉換回 String,而第三種方法僅使用一個 StringBuilder 完成整個過程。
我個人更喜歡Strings.format()
,簡單易讀的單行字符串格式化程序。
String b = "B value";
String d = "D value";
String fullString = String.format("A %s C %s E F", b, d);
// Output: A B value C D value E F
使用+
運算符是最佳實踐,它也簡單易讀。
Java 語言為字符串連接運算符 (+) 以及將其他對象轉換為字符串提供特殊支持。 字符串拼接是通過StringBuilder(或StringBuffer) class 及其 append 方法實現的。
官方文檔:https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
在字節碼級別沒有什么不同,我們不會在那里影響效率。 如果執行字節碼級別,則必須通過調用append對+進行非內聯運算符重載方法go。然后在匯編語言級別(Java編寫C和C產生類似於匯編的程序集,會有額外的寄存器調用store + method call in the stack 並且會有額外的push。(實際上,交叉編譯器可能會優化 + operator call,在這種情況下與效率沒有區別。)
有一種提高可讀性的方法是一種很好的做法。 :)
所有的答案都非常好並且具有解釋性。 但我覺得探索其他字符串連接技術也會有所幫助,比如 Guava Joiner、Streams、String.format 等。
有關每種連接技術java-string-concatenation-which-way-is-best性能的完整詳細信息。
簡而言之,級聯性能隨編號而變化。 要連接的字符串。 例如 - 要連接 1-10 個字符串,這些技術最有效 - StringBuilder、StringBuffer 和 Plus Operator。 並連接 100 個字符串 - Guava Joiner,apache 的 stringsUtils 庫也很好用。
請go通過以上博客。 它確實很好地解釋了性能效率。
謝謝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.