java 板


LINE

(我知道這篇有點久,我一直想回可是一直都忘了) 第一眼看到裡面的 test code, 就覺得不太對勁。 我想是原文作者對 "+ 會轉成 StringBuffer/StringBuilder" 這句話的意思有誤解吧。 在書上(忘了哪一本,印象中很多書都有提到)看到的是, String 的 + 是會轉化為 StringBuffer,但這是指 compilation 的過程,當 compiler 看到 aString + x + y + z; 會把它替換為 new StringBuffer(aString).append(x).append(y).append(z).toString(); 而已。(JDK5+ 則用 StringBuilder) (我相信這是在 JLS 有規範的可是我沒去找 :P ) 原文中做的是 result = a + b; result = result + c; 這類的動作 旨望 JIT 做 optimization 還有可能,可是 compiler 大概 不會做什麼特別動作: result = new StringBuffer(a).append(b).toString(); result = new StringBuffer(result).append(c).toString(); 想當然爾,這樣的 code 和 result = new StringBuffer(a).append(b).append(c).toString(); 相比一定比較慢。 問題是,Compiler 不會跨 expression 做這類 optimization 很 正常呀。 要是原本做的就是 result = a + b + c; 我猜結果應該沒什麼大分別。 然後大概有人會問,反正都是替換成 StringBuffer/StringBuilder 那麼倒不如不要用 +, 一直都用 StringBuilder 不就保險了嗎? 並不是! 我想到的就有三大原因: 1) 很多情況下 + 比較好讀,尤其一句 expression 裡串連一堆 string, 用 StringBuilder 累贅得不得了 2) 由 JDK5 開始,+ 會用 StringBuilder. 要是有一些 JDK5 以前寫的 code 在沒有修改下 recompile, 用 + 的會因為由 StringBuffer 轉 成 StringBuilder 而有效能增長,但手工 StringBuffer 就沒了 3) 最重要的原因,有時 + 會跑很比手工 StringBuilder 快。 問題就出在 String literal 身上: String result = "some " + "string " + "literals"; vs String result = new StringBuilder("some ") .append("string ") .append("literals") .toString(); 第一種情況下,Compiler 是會把 string literal 連成一個literal, 而又因為是直接 assign, 又省了 string builder, 變成: String result = "some string literals"; 另外有人把用 StringBuilder 類比為 premature optimization 或 over-design,而主張只用 +/+= 。我實在不能苟同。與其期 望 JIT 或許可以幫忙 optimize (可是本身又不清楚 JIT 可以 達到的範圍),倒不如在不影響程式可讀性的情況下選擇恰當的 string 串接手段。 String sql = "select balblabla from table where a=b"; if (c) { sql += "and c = d"; } if (e) { sql += "and e = f"; }; 相比 StringBuilder sql = new StringBuilder("select balblabla from table where a=b"); if (c) { sql.append("and c = d"); } if (e) { sql.append("and e = f"); }; 後者真的有比較難讀嗎? 可是前者卻是當 c 與 e 都出現的時候,白白浪費了兩個 StringBuilder。 當然只有一兩個看起來沒啥分別,可是當成了習慣或 convention,十個二十 個 criteria 也自然會用一樣的方法來寫。這還能接受嗎? 個人簡單的規則:當你的 string concatenation 只是在一句 expression 內,請用 +, 否則請用 StringBuilder. --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 223.19.42.175 ※ 編輯: adrianshum 來自: 223.19.42.175 (04/19 09:46)
1F:→ swpoker:如果只有組個幾句就沒差拉~但大量處理字串就真的有差了 04/19 10:36
2F:→ adrianshum:我著眼點是在於 convention。類同的東西,應避免有時用 04/19 21:22
3F:→ adrianshum:這種有時用那種方法寫。 04/19 21:22







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:e-shopping站內搜尋

TOP