亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

初始化 StringBuilder 以使用 UTF-16 編碼器

初始化 StringBuilder 以使用 UTF-16 編碼器

慕桂英3389331 2022-12-21 16:34:23
考慮 Java 11 中的以下代碼:StringBuilder sb = new StringBuilder("one"); sb.append("δ?ο");  // "two"第一行創建一個StringBuilder使用 Latin1 編碼器的代碼(每個字符一個字節)。然后第二行使 StringBuilder 意識到它需要改用 UTF16 編碼器,因此它在附加新的 UTF-16 字符之前將其當前內容復制到一個新數組中。StringBuilder 類有一個構造函數重載,它接受一個初始容量參數,如果您已經知道要構建的字符串的所需大小,它旨在避免重新分配。但是如果你從一個英文字符串開始,然后附加一個外國字符串,這個特殊的構造函數重載就沒有用了,因為它仍然重新分配字節數組。有沒有辦法創建一個從一開始就使用 UTF16 的 StringBuilder 實例?
查看完整描述

3 回答

?
catspeake

TA貢獻1111條經驗 獲得超0個贊

Java 11 或 Java 12 版本中沒有任何東西StringBuilder可以做到這一點。

真正的問題是您可能從中獲得的性能提升對您有多重要。 分析您的應用程序以了解這種不需要的重新分配是否對您的應用程序的整體性能有顯著影響。

如果它要產生重大影響,您可以實現自己的版本StringBuilder(擴展相同的接口以實現兼容性)。

或者,如果您準備等待,您可以下載 OpenJDK 源代碼并開發/構建/測試擴展以StringBuilder……并將其作為補丁提交以供考慮。(如果您包含了顯示出明顯性能優勢的基準,那將有助于增加包含的機會。)


查看完整回答
反對 回復 2022-12-21
?
素胚勾勒不出你

TA貢獻1827條經驗 獲得超9個贊

對此做了更多研究后,我為我自己的問題提供了另一個答案(Stack Overflow 說回答你自己的問題是完全可以接受的。)

正如Slawomir 所說,無論如何,StringBuilder 都會使用 Latin1 進行初始化。因此,假設您主要使用俄語、中文、印地語或希臘語等語言寫作。您想要構建一個已知其最大大小的字符串,因此您使用初始容量參數:

StringBuilder sb = new StringBuilder(4096);
sb.append("Здравствуйте!");  // Should easily fit in 4 kilobytes, right?

然而,上面的調用append會丟棄您之前初始化的 4KB 緩沖區并分配一個新緩沖區。您構造了具有初始容量的 StringBuilder 以避免重新分配緩沖區,但 StringBuilder 無論如何都重新分配了它。它重新分配了它,即使它已經足夠大了!

解決方法是使用 JVM 選項運行 java -XX:-CompactStrings。

如果您始終使用其中一種語言,那么您的字符串無論如何都會使用 UTF-16,因此在啟動時關閉字符串壓縮將減少檢查您提供的每個字符串以查看它是否可以使用 Latin1 編碼存儲的開銷。

另請參閱Heinz Kabutz 于 2019 年 5 月 29 日在保加利亞 jPrime 上的演講,其中他導致 StringBuilder 由于此“功能”而耗盡內存。


查看完整回答
反對 回復 2022-12-21
?
青春有我

TA貢獻1784條經驗 獲得超8個贊

似乎沒有明顯的。如果您想影響 StringBuffer 初始化的方式,我的建議是創建一個實用程序“初始化器”來實現CharSequence和使用相應的 StringBuilder 構造函數。您可以使用它來傳達任何長度和字符內容,并且 StringBuilder 內部應該足夠聰明以接受它。

不過,看看 OpenJDK 11 的實現,它似乎無論如何都要從 Latin1 開始。某種形式的重新分配似乎總是會發生。


查看完整回答
反對 回復 2022-12-21
  • 3 回答
  • 0 關注
  • 161 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號