簡體   English   中英

最佳實踐/性能:將 StringBuilder.append 與 String.concat 混合

[英]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創建可以同時容納s1s2char[]數組。 s1s2的內容復制到這個新數組。 實際上比+運算符需要更少的工作。

StringBuilder.append()

維護一個在需要時增長的內部char[]數組。 如果內部字符足夠大,則不會創建額外的char[]

stringBuilder.append(s1.concat(s2))

也表現不佳,因為s1.concat(s2)創建了一個額外的char[]數組並將s1s2復制到它只是為了將新數組內容復制到內部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();

直接取自Java Oracles 網站上的最佳實踐

您應該始終使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM