Re: [翻譯] 拆穿 Java StringBuilder 的謠言

看板java作者 (Alien)時間11年前 (2013/04/19 09:43), 編輯推噓0(003)
留言3則, 2人參與, 最新討論串8/8 (看更多)
(我知道這篇有點久,我一直想回可是一直都忘了) 第一眼看到裡面的 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)

04/19 10:36, , 1F
如果只有組個幾句就沒差拉~但大量處理字串就真的有差了
04/19 10:36, 1F

04/19 21:22, , 2F
我著眼點是在於 convention。類同的東西,應避免有時用
04/19 21:22, 2F

04/19 21:22, , 3F
這種有時用那種方法寫。
04/19 21:22, 3F
文章代碼(AID): #1HSA4cNR (java)
討論串 (同標題文章)
文章代碼(AID): #1HSA4cNR (java)