搜尋
首頁Javajava教程Java的StringBuilder在高效能場景下怎麼正確使用

StringBuilder在高性能場景下的正確用法

關於StringBuilder,一般同學只簡單記住了,字串拼接要用StringBuilder,不要用+,也不要用StringBuffer,然後效能就是最好的了,真的嗎?

還有些同學,還聽過三句似是而非的經驗:

1. Java編譯優化後+和StringBuilder的效果一樣;

2. StringBuilder不是線程安全的,為了「安全」起見最好還是用StringBuffer;

3. 永遠不要自己拼接日誌訊息的字串,交給slf4j來。

1. 初始長度好重要,值得說四次。

StringBuilder的內部有一個char[], 不斷的append()就是不斷的往char[]裡填東西的過程。

new StringBuilder() 時char[]的預設長度是16,然後,如果要append第17個字符,怎麼辦?

用System.arraycopy倍增擴充擴充! ! ! !

這樣一來有陣列拷貝的成本,二來原來的char[]也白白浪費了要被GC掉。可以想見,一個129字元長度的字串,經過了16,32,64, 128四次的複製和丟棄,合共申請了496字元的數組,在高性能場景下,這幾乎不能忍。

所以,合理設定一個初始值多重要。

但如果我實在估算不好呢?多估一點點好了,只要字串最後大於16,就算浪費一點點,也比成倍的擴容好。

2. Liferay的StringBundler類別

Liferay的StringBundler類別提供了另一個長度設定的思路,它在append()的時候,不急著往char[]裡塞東西,而是先拿一個String[]把它們都存起來,到了最後才把所有String的length加起來,建構一個合理長度的StringBuilder。

3. 但,還是浪費了一倍的char[]

#浪費發生在最後一步,StringBuilder.toString()

// Create a copy , don't share the array
return new String(value, 0, count);

String的建構子會用System.arraycopy()複製一把傳入的char[]來確保安全性不可變性,如果故事就這樣結束,StringBuilder裡的char[]還是被白白犧牲了。

為了不浪費這些char[],一種方法是用Unsafe之類的各種黑科技,繞過建構子直接給String的char[]屬性賦值,但很少人這樣做。

另一個可靠的方法就是重複使用StringBuilder。而重用,也解決了前面的長度設定問題,因為即使一開始估算不準,多擴容幾次之後也夠了。

4. 重複使用StringBuilder

這個做法來自JDK裡的BigDecimal類別(沒事看看JDK程式碼多重要),SpringSide裡將程式碼提取成StringBuilderHolder,裡面只有一個函數

public StringBuilder getStringBuilder() {
sb.setLength(0);
return sb;
}

StringBuilder.setLength()函數只重置它的count指針,而char[]則會繼續重用,而toString()時會把目前的count指針也當作參數傳給String的建構函數,所以不用擔心把超過新內容大小的舊內容也傳進去了。可見,StringBuilder是完全可以重複使用的。

為了避免併發衝突,這個Holder一般設為ThreadLocal,標準寫法見BigDecimal或StringBuilderHolder的註釋。

5. + 與StringBuilder

String s = “hello ” user.getName();

這句話經過javac編譯後的效果,的確等價於使用StringBuilder,但沒有設定長度。

String s = new StringBuilder().append(“hello”).append(user.getName());

但是,如果像下面這樣:

String s = “hello ”;
// 隔了其他一些語句
s = s + user.getName();

#每一語句,都會產生一個新的StringBuilder,這裡就有了兩個StringBuilder,效能就完全不一樣了。如果是在循環體裡s =i; 就更加多到沒譜。

據R大說,努力的JVM工程師們在運行優化階段, 根據XX: OptimizeStringConcat(JDK7u40後默認打開),把相鄰的(中間沒隔著控制語句) StringBuilder合成一個,也會努力的猜長度。

所以,保險起見還是繼續自己用StringBuilder並設定長度好了。

6. StringBuffer 與 StringBuilder

StringBuffer與StringBuilder都是繼承於AbstractStringBuilder,唯一的差別就是StringBuffer的函數上都有synchronized關鍵字。

那些說StringBuffer 「安全」的同學,其實你幾時看過幾個線程輪流append一個StringBuffer的狀況? ? ?

7. 永遠把日誌的字串拼接交給slf4j??

logger.info("Hello {}", user.getName());

#對於不知道要不要輸出的日誌,交給slf4j在真的需要輸出時才去拼接的確能省節約成本。

但對於一定要輸出的日誌,直接自己用StringBuilder拼接更快。因為看看slf4j的實現,其實就是不斷的indexof("{}"), 不斷的subString(),再不斷的用StringBuilder拼起來而已,沒有銀彈。

PS. slf4j中的StringBuilder在原始Message之外預留了50個字符,如果可變參數加起來長過50字符還是得複製擴容......而且StringBuilder也沒有重用。

以上是Java的StringBuilder在高效能場景下怎麼正確使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
如何處理在IDEA中連接Oracle數據庫時出現的數字溢出錯誤?如何處理在IDEA中連接Oracle數據庫時出現的數字溢出錯誤?Apr 19, 2025 pm 04:15 PM

在IDEA中連接Oracle數據庫時出現數字溢出錯誤的處理方法當我們在使用IntelliJ...

@ResultType註解在MyBatis中如何正確使用?@ResultType註解在MyBatis中如何正確使用?Apr 19, 2025 pm 04:12 PM

在研究MyBatis框架時,開發者們常常會遇到關於註解的各種問題,其中一個常見的問題是如何正確使用@ResultType注...

如何利用自然語言處理技術高效查詢人員數據?如何利用自然語言處理技術高效查詢人員數據?Apr 19, 2025 pm 04:09 PM

利用自然語言處理技術查詢人員數據的方法在現代企業中,人員數據的管理和查詢是一個常見的需求。假設我們...

SpringBoot多數據源配置下,數據庫訪問白天慢夜間快是什麼原因?SpringBoot多數據源配置下,數據庫訪問白天慢夜間快是什麼原因?Apr 19, 2025 pm 04:06 PM

Springboot項目多數據源配置下的數據庫訪問性能問題排查本文針對一個Springboot項目中使用Atomikos進行多數據源配�...

Java項目打包成JAR後出現NoClassDefFoundError: 如何排查JDK版本兼容性問題?Java項目打包成JAR後出現NoClassDefFoundError: 如何排查JDK版本兼容性問題?Apr 19, 2025 pm 04:03 PM

Java項目打包成可執行JAR文件時遭遇NoClassDefFoundError難題很多Java開發者在將項目打包成可執行JAR文件時,可能會�...

如何分析IntelliJ IDEA的破解過程並找到負責註冊的lib或class?如何分析IntelliJ IDEA的破解過程並找到負責註冊的lib或class?Apr 19, 2025 pm 04:00 PM

關於IntelliJIDEA破解的分析方法在編程界,IntelliJ...

如何使用Java和JavaCV提升視頻質量?為什麼效果有限?如何使用Java和JavaCV提升視頻質量?為什麼效果有限?Apr 19, 2025 pm 03:57 PM

問題介紹:視頻質量提升是視頻處理中的一個重要環節,尤其是在處理低清晰度的視頻時,如何利用Java語言和�...

如何讓SpringBoot中的@RequestBody註解正確接收非JSON格式的字符串參數?如何讓SpringBoot中的@RequestBody註解正確接收非JSON格式的字符串參數?Apr 19, 2025 pm 03:54 PM

在處理SpringBoot應用中,我們經常會遇到如何正確接收請求參數的問題。特別是當參數格式不是常見的JSON時,更�...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具