Java又被噴了 String的append

趙姐夫在info q 上的ppt

開吵的緣由

姐夫說

看到群里有人貼這個(gè)搔确。Java編譯器真的會(huì)把普通的字符串拼接操作“優(yōu)化”為StringBuilder字币?有這么糟蹋性能的做法嗎? ????

嗯... 小萌新表示 還好吧. 否則每次在常量空間中創(chuàng)建一個(gè)中間值 這樣子多不值當(dāng). (雖然的在新的JVM標(biāo)準(zhǔn)中 已經(jīng)把String 從常量空間挪到新生區(qū)域了

這是個(gè)嚴(yán)重影響性能的做法不是嗎?明明目標(biāo)字符串長度也可以知道胚委,你搞個(gè)SB需要額外字符數(shù)組翻幾次倍最后再復(fù)制一份课竣,怪不得總是要和GC作斗爭嘉赎,這么個(gè)基礎(chǔ)操作都這么浪費(fèi)置媳。

原來Java出了二十幾年,.NET出了十五年了公条,到現(xiàn)在還有那么多人連如何高效地拼接字符串拇囊,什么時(shí)候該使用StringBuilder什么時(shí)候不該使用都不清楚。還有人說一萬個(gè)字符串拼接用SB就快了等等靶橱,當(dāng)然不是寥袭。SB的使用場(chǎng)景是目標(biāo)字符串長度不確定的情況,和到底是十個(gè)還是十萬個(gè)字符串关霸,到底最終長度是一百還是一百萬都沒有關(guān)系传黄。比如之前的場(chǎng)景,每個(gè)字符串都是確定的队寇,最終長度自然也是確定的膘掰,這根本就不應(yīng)該動(dòng)用SB。假如你不知道應(yīng)該怎么做佳遣,那只能讓你去看下十五年前開始.NET就采取的做法识埋。在目標(biāo)字符串長度確定的情況下,出現(xiàn)目標(biāo)字符串外任意一個(gè)額外的內(nèi)存分配都是不及格零渐。

另外有人說“一個(gè)”StringBuilder對(duì)象惭聂,好像沒多少開銷一樣。但是SB不是一個(gè)對(duì)象相恃,而是一串對(duì)象啊辜纲。你append過程中隨時(shí)就會(huì)分配一個(gè)長度翻倍的新的char數(shù)組,然后還要復(fù)制一遍拦耐。多少人以為用SB就夠了一樣耕腾,都不知道需要指定一個(gè)capacity。
比如那段所謂被Java編譯器“優(yōu)化”的代碼杀糯,capacity也沒指定扫俺,翻倍和復(fù)制幾乎肯定發(fā)生。當(dāng)然假如他們知道指定capacity固翰,也不會(huì)使用SB這么低效的做法了吧狼纬。

剛才忘記切換jdk了,java9 已經(jīng)不是這樣了骂际,會(huì)使用makeConcatWithConstants 進(jìn)行拼接

至于非final時(shí)用append來搞疗琉,從JDK 1.1時(shí)代就是這么玩了。當(dāng)然歉铝,還是寫javac的人偷懶盈简,先確定長度再生成SB會(huì)好一些,但是碰到為null時(shí)怎么調(diào)用xxx.length(),搞到最后變成這樣: 網(wǎng)頁鏈接

正確的字符串拼接方式 網(wǎng)頁鏈接 算出總長柠贤,分配目標(biāo)字符串內(nèi)存香浩,把輸入的字符串復(fù)制到正確的位置。出現(xiàn)任意額外的StringBuilder啊char數(shù)組分配什么的都是不及格臼勉。 ????

我是真不知道直到 Java 9 才有 StringConcatFactory 這種東西的邻吭,所以才沒能理解為什么 Java 程序員普遍覺得除了 .append 就只有 StringBuilder 一途

至于為什么 .NET 這邊不鼓勵(lì)濫用 StringBuilder,我覺得就算想一下為什么 Java 9 會(huì)有 StringConcatFactory 也該明白了宴霸。

多說一句镜盯,其實(shí)StringBuilder在拼接字符串時(shí)也不一定是最優(yōu)的,因?yàn)樗鋵?shí)是把每次Append進(jìn)去的東西復(fù)制展開猖败,因此內(nèi)存占用是和目標(biāo)字符串長度相關(guān)的速缆。有時(shí)候,你拿一個(gè)字符串?dāng)?shù)組/List保留輸入字符串恩闻,最后用自己寫的Concat(string[] input, beginIndex, length)拼起來艺糜,此時(shí)額外的內(nèi)存占用就是和字符串?dāng)?shù)量相關(guān),就遠(yuǎn)小于目標(biāo)字符串長度了幢尚。而這個(gè)臨時(shí)字符串?dāng)?shù)組甚至都可以復(fù)用破停,最終效果便又是零(額外)分配了。當(dāng)然尉剩,這種方法并不是沒有值得討論的地方真慢。一是實(shí)際開發(fā)時(shí),復(fù)用一個(gè)巨型的StringBuilder理茎,每線程一個(gè)(ThreadStatic)黑界,這可能也夠了,開發(fā)起來也更方便(效果相對(duì)略差)皂林。二是用StringBuilder時(shí)朗鸠,每次Append的字符串可能可以被立即回收,而用上邊描述的方法會(huì)導(dǎo)致字符串被長時(shí)間引用而被升代(假如它們本身就會(huì)被其他地方引用著那么自然就沒這方面問題了)础倍≈蛘迹總之內(nèi)存優(yōu)化時(shí)很多時(shí)候就是圍繞字符串來的,畢竟字符串代表的是一大塊連續(xù)內(nèi)存沟启,而且太容易生成新字符串(Split忆家,ToUpper,Substring等等)德迹,操作起來要么浪費(fèi)要么麻煩芽卿。更有甚者是,它很容易/已經(jīng)被濫用了浦辨,例如目標(biāo)函數(shù)就是要接受一個(gè)字符串時(shí)蹬竖,你除了生成一個(gè)新的就沒其他辦法了沼沈。用Span<char>可以解決部分問題流酬,但它一是太新用不上币厕,二是也不能解決所有問題。收起全文

JEP280 為提高性能所做的努力 ????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芽腾,一起剝皮案震驚了整個(gè)濱河市旦装,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摊滔,老刑警劉巖阴绢,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異艰躺,居然都是意外死亡呻袭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門腺兴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來左电,“玉大人,你說我怎么就攤上這事页响÷ㄗ悖” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵闰蚕,是天一觀的道長栈拖。 經(jīng)常有香客問我,道長没陡,這世上最難降的妖魔是什么涩哟? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮盼玄,結(jié)果婚禮上染簇,老公的妹妹穿的比我還像新娘。我一直安慰自己强岸,他們只是感情好锻弓,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蝌箍,像睡著了一般青灼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妓盲,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天杂拨,我揣著相機(jī)與錄音,去河邊找鬼悯衬。 笑死弹沽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播策橘,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼炸渡,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了丽已?” 一聲冷哼從身側(cè)響起蚌堵,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沛婴,沒想到半個(gè)月后吼畏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嘁灯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年泻蚊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丑婿。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡性雄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出枯冈,到底是詐尸還是另有隱情毅贮,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布尘奏,位于F島的核電站滩褥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏炫加。R本人自食惡果不足惜瑰煎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俗孝。 院中可真熱鬧酒甸,春花似錦、人聲如沸赋铝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽革骨。三九已至农尖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間良哲,已是汗流浹背盛卡。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留筑凫,地道東北人滑沧。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓并村,卻偏偏與公主長得像,于是被迫代替她去往敵國和親滓技。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哩牍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Tip:筆者馬上畢業(yè)了,準(zhǔn)備開始 Java 的進(jìn)階學(xué)習(xí)計(jì)劃殖属。于是打算先從 String 類的源碼分析入手姐叁,作為后面...
    石先閱讀 12,018評(píng)論 16 58
  • 集合框架: 1)特點(diǎn):存儲(chǔ)對(duì)象瓦盛;長度可變洗显;存儲(chǔ)對(duì)象的類型可不同2)Collection(1)List:有序的;元素...
    Demo_Yang閱讀 1,269評(píng)論 0 4
  • 太乙翠溪苑原环,六個(gè)新同學(xué)挠唆。已是半夜深睡時(shí),相約尋門去嘱吗。一抹木碳火玄组,兩把簽子肉,幾瓶啤酒論相逢谒麦,歸來親如故俄讹。
    云水居士閱讀 374評(píng)論 1 2
  • 從叢林到農(nóng)田,我們用了幾百萬年绕德,這不漫長患膛,緊迫的戰(zhàn)斗和進(jìn)化從未停止。從農(nóng)田到城市耻蛇,我們只用了幾十年踪蹬,時(shí)間越來越不夠...
    王子啊閱讀 128評(píng)論 0 0
  • 豬爸堅(jiān)強(qiáng)系列12: 一直以來XW聯(lián)播中人民一片祥和娶聘、太平,生活在幸福中截型; 尤其有個(gè)大記者隨便在街頭逮個(gè)人問:你幸福...
    商業(yè)辦公設(shè)計(jì)師木易閱讀 206評(píng)論 0 0