3 回答

TA貢獻(xiàn)1111條經(jīng)驗(yàn) 獲得超0個贊
Java 11 或 Java 12 版本中沒有任何東西StringBuilder
可以做到這一點(diǎn)。
真正的問題是您可能從中獲得的性能提升對您有多重要。 分析您的應(yīng)用程序以了解這種不需要的重新分配是否對您的應(yīng)用程序的整體性能有顯著影響。
如果它要產(chǎn)生重大影響,您可以實(shí)現(xiàn)自己的版本StringBuilder
(擴(kuò)展相同的接口以實(shí)現(xiàn)兼容性)。
或者,如果您準(zhǔn)備等待,您可以下載 OpenJDK 源代碼并開發(fā)/構(gòu)建/測試擴(kuò)展以StringBuilder
……并將其作為補(bǔ)丁提交以供考慮。(如果您包含了顯示出明顯性能優(yōu)勢的基準(zhǔn),那將有助于增加包含的機(jī)會。)

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超9個贊
對此做了更多研究后,我為我自己的問題提供了另一個答案(Stack Overflow 說回答你自己的問題是完全可以接受的。)
正如Slawomir 所說,無論如何,StringBuilder 都會使用 Latin1 進(jìn)行初始化。因此,假設(shè)您主要使用俄語、中文、印地語或希臘語等語言寫作。您想要構(gòu)建一個已知其最大大小的字符串,因此您使用初始容量參數(shù):
StringBuilder sb = new StringBuilder(4096); sb.append("Здравствуйте!"); // Should easily fit in 4 kilobytes, right?
然而,上面的調(diào)用append
會丟棄您之前初始化的 4KB 緩沖區(qū)并分配一個新緩沖區(qū)。您構(gòu)造了具有初始容量的 StringBuilder 以避免重新分配緩沖區(qū),但 StringBuilder 無論如何都重新分配了它。它重新分配了它,即使它已經(jīng)足夠大了!
解決方法是使用 JVM 選項運(yùn)行 java -XX:-CompactStrings
。
如果您始終使用其中一種語言,那么您的字符串無論如何都會使用 UTF-16,因此在啟動時關(guān)閉字符串壓縮將減少檢查您提供的每個字符串以查看它是否可以使用 Latin1 編碼存儲的開銷。
另請參閱Heinz Kabutz 于 2019 年 5 月 29 日在保加利亞 jPrime 上的演講,其中他導(dǎo)致 StringBuilder 由于此“功能”而耗盡內(nèi)存。

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超8個贊
似乎沒有明顯的。如果您想影響 StringBuffer 初始化的方式,我的建議是創(chuàng)建一個實(shí)用程序“初始化器”來實(shí)現(xiàn)CharSequence
和使用相應(yīng)的 StringBuilder 構(gòu)造函數(shù)。您可以使用它來傳達(dá)任何長度和字符內(nèi)容,并且 StringBuilder 內(nèi)部應(yīng)該足夠聰明以接受它。
不過,看看 OpenJDK 11 的實(shí)現(xiàn),它似乎無論如何都要從 Latin1 開始。某種形式的重新分配似乎總是會發(fā)生。
添加回答
舉報