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灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP