日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

string拼接_String拼接操作-的优化

發(fā)布時間:2025/3/12 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 string拼接_String拼接操作-的优化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

很多講Java優(yōu)化的文章都會強調(diào)對String拼接的優(yōu)化。倒不用特意記,本質(zhì)上在于對不可變類優(yōu)勢和劣勢的理解上。

需要關(guān)注的是編譯器對String拼接做出的優(yōu)化,在簡單場景下的性能能夠與StringBuilder相當,復雜場景下仍然有較大的性能問題。網(wǎng)上關(guān)于這一問題講的非常亂;如果我講的有什么紕漏,也歡迎指正。

本文用到了反編譯工具jad。在查閱網(wǎng)上關(guān)于String拼接操作的優(yōu)化時發(fā)現(xiàn)了這個工具,能同時反編譯出來源碼和字節(jié)碼,親測好用,點我下載。

String拼接的性能問題

優(yōu)化之前,每次用”+”拼接,都會生成一個新的String。特別在循環(huán)拼接字符串的場景下,性能損失是極其嚴重的:

  • 空間浪費:每次拼接的結(jié)果都需要創(chuàng)建新的不可變類
  • 時間浪費:創(chuàng)建的新不可變類需要初始化;產(chǎn)生大量“短命”垃圾,影響 young gc甚至full gc
  • 所謂簡單場景

    簡單場景和復雜場景是我亂起的名字,幫助理解編譯器的優(yōu)化方案。

    簡單場景可理解為在一句中完成拼接:

    int?i?=?0;String?sentence?=?“Hello”?+?“world”?+?String.valueOf(i)?+?“”;System.out.println(sentence);

    利用jad可看到優(yōu)化結(jié)果:

    int?i?=?0;String?sentence?=?(new?StringBuilder()).append(“Hello”).append(“world”).append(String.valueOf(i)).append(“”).toString();System.out.println(sentence);

    是不是很神奇,竟然把String的拼接操作優(yōu)化成了StringBuilder#append()!

    此時,可以認為已經(jīng)將簡單場景的空間性能、時間性能優(yōu)化到最優(yōu)(僅針對String拼接操作而言),看起來編譯器已經(jīng)完成了必要的優(yōu)化。你可以測試一下,簡單場景下的性能能夠與StringBuilder相當。但是——“但是”以前的都是廢話——編譯器的優(yōu)化對于復雜場景的幫助卻很有限了。

    所謂復雜場景

    所謂復雜場景,可理解為“編譯器不確定(或很難確定,于是不做分析)要進行多少次字符串拼接后才需要轉(zhuǎn)換回String”??赡鼙硎霾粶蚀_,理解個大概就好。

    我們分析一個最簡單的復雜場景:

    String?sentence?=?“”;for?(int?i?=?0;?i?

    理想的優(yōu)化方案

    當然,無論什么場景,程序猿都可以手動優(yōu)化:

    • 在性能敏感的場景使用StringBuilder完成拼接。
    • 在性能不敏感的場景使用更方便的String。

    PS:別吐槽,這樣的API設(shè)計是合理的,在合適的地方做合適的事。

    理想目標是把這件事交給javac和JIT:

    • 設(shè)定一個拼接次數(shù)的閾值,超過閾值就啟動優(yōu)化(對于javac有一個編譯期的閾值,JIT有一個運行期的閾值,以分階段優(yōu)化)。
    • 優(yōu)化時,在拼接前生成StringBuilder對象,將拼接操作換成StringBuilder#append(),繼續(xù)使用該對象,直至“需要”String對象時,使用StringBuilder#toString()“懶加載”新的String對象。

    該優(yōu)化方案的難度在于代碼分析:機器很難知道到底何時“需要”String對象,所以也很難在合適的位置注入代碼完成“懶加載”。

    雖然很難實現(xiàn),但還是給出理想的優(yōu)化結(jié)果,以供實際方案對比:

    String?sentence?=?“”;StringBuilder?sentenceSB?=?new?StringBuilder(sentence);for?(int?i?=?0;?i?

    實際的優(yōu)化方案

    利用jad查看實際的優(yōu)化結(jié)果:

    String?sentence?=?“”;for?(int?i?=?0;?i?

    可以看到,實際上編譯器的優(yōu)化只能達到簡單場景的最優(yōu):僅優(yōu)化字符串拼接的一句。這種優(yōu)化程度,對于上述復雜場景的性能提升很有限,循環(huán)時還是會生成大量短命垃圾,特別是字符串拼接到很大的時候,空間和時間上都是致命的。

    通過對理想方案的分析,我們也能理解編譯器優(yōu)化的無奈之處:編譯器無法(或很難)通過代碼分析判斷何時是最晚進行懶加載的時機。為什么呢?我們將代碼換個形式可能更容易理解:

    String?sentence?=?“”;for?(int?i?=?0;?i?

    觀察第3行的代碼,等式右側(cè)引用了sentence。我肉眼知道這句話只完成了字符串拼接,機器呢?最起碼,現(xiàn)在的機器還很難通過代碼判斷。

    待以后將人工智能與編譯優(yōu)化結(jié)合起來,就算只能以90%的概率完成優(yōu)化,也是非常cool的。

    總結(jié)

    這個問題我沒有做性能測試。其實也沒必要過于深究,與其讓編譯器以隱晦的方式完成優(yōu)化,不如用代碼進行主動、清晰的優(yōu)化,讓代碼能夠“自解釋”。

    那么,如果需要優(yōu)化,使用StringBuilder吧。

    總結(jié)

    以上是生活随笔為你收集整理的string拼接_String拼接操作-的优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。