作者adrianshum (Alien)
看板java
标题Re: [翻译] 拆穿 Java StringBuilder 的谣言
时间Fri Apr 19 09:42:59 2013
(我知道这篇有点久,我一直想回可是一直都忘了)
第一眼看到里面的 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