作者swpoker (swpoker)
看板java
标题Re: [翻译] 拆穿 Java StringBuilder 的谣言
时间Tue Apr 2 12:03:28 2013
这个我在系统最常见的范例就是
StringBuffer sb = new StringBuffer();
sb.append("select * from a");
sb.append(" where 1=1 ");
if( XXX ) {
sb.append(" and aaa = 'bbb' ");
}
if( AAA ){
sb.append(" and akk = 'bkk' ");
}
然後就没了
其实跟
String sql = "select * from a";
sql += " where 1=1 ";
if( XXX ) {
sql+=" and aaa = 'bbb' ";
}
if( AAA ){
sql+=" and akk = 'bkk' ";
}
老实说没什麽两样
因为程式少到几乎没有什麽差异
况且要把
sql+=""
改成
sql.append("")
也是很简单的
但我发现~其实很多人是很害怕重构~害怕修改~
宁愿一开始就什麽都想 什麽都做 (其实有很多是不必要的设计规划)
然後改个程式就感到十分可怕,似乎是世界末日一样
所以即时发现这样会有不必要的程式码出现也在所不惜
因为在处理大量字串的时候会有效能上的考量
可惜实际上却很少有这样的机会考验效能
除非要进行大量字串处理
不然
"+" 其实没有很可怕阿
我自己的作法就是
先用 "+"
如果有大量效能的考量
在改成StringBuffer or StringBuilder
实际上在一般客制化应用系统中,要处理大量字串的机率真的不高
真的没有必要说 ,一开始光是处理字串,就通通用StringBuilder
我想这有点过头了
况且jdk可是会最佳化的阿
我相信JDK!!!
PS.上述SQL中的 "1=1"是不好的~可惜很常见
※ 引述《sbrhsieh (十年~)》之铭言:
: ※ 引述《cyclone350 (老子我最神)》之铭言:
: : 大概看懂版主跟那篇文章是啥意思了,我用白话一点 (有务请修正)
: : 如果你的程式码长这样
: : String str = '';
: : while(i < 100000) {
: : str += 'a';
: : }
: : jdk 会把回圈解释成像这样
: : while(i < 100000) {
: : str = new StringBuilder(str).append('a');
: : }
: : 但是如果你自己用 StringBuilder 的话会是这样用
: : StringBuilder str = new StringBuilder();
: : while(i < 100000) {
: : str.append('a');
: : }
: : 所以差在的时间应该很明显在哪边 !!
: : 虽然 + 号会被解释成 append,但是他不是万用的
: : 在某些情况仍需要自行使用 StringBuilder 来提升效能
: : 这应该就是那边文章的结论 !?
: 这一串讨论看来有些紊乱。
: 我本来以为多数的人都已经知道在回圈内使用 operator + 来串接字串做累加的
: 恐怖(在时间与空间上)与原因,毕竟 JWorld@TW 上这一篇文章已挂了好多年了。
: http://www.javaworld.com.tw/jute/post/view?bid=29&id=15160&sty=1&tpg=3&age=-1
: 在程式码中一个以 operator + 串接多个 sub-expression 的 expression 在编译
: 其会被编译器换成 StringBuffer(for Java 1.5-)/StringBuilder(for Java 1.5+)
: 的多个操作(若是各 sub-expression 都是编译期常数,则整个 expression 由
: 编译器替换成一个常数)。
: 通常临时要把多个数值组合成一个字串时,直接用 operator + 串起来是无大碍。
: 但偏偏许多初心者很喜欢用在回圈里使用 operator + 来集成一个最後的结果字串,
: 如同你文中的第一个例子。
: 这种做法恐怖在对空间与时间上的浪费,把 StringBuffer/StringBuilder 比喻成
: 笔记簿,这样子的行为就如同一个人在学期初买了一张纸当笔记簿。
: 上了一堂课後,发现他的笔记簿已经用完,於是他又去买了两张纸当作新
: 笔记簿,还记得先把前一本笔记簿(一张纸)的内容抄写过来。
: 上了第二堂课,又发现笔记簿用完了,於是再去买三张纸成为新笔记簿,也记得
: 把前一本笔记簿(两张纸)的内容抄写到新笔记簿里。
: 上了第三堂课,又发现笔记簿用完了,於是再去买四张纸成为新笔记簿,也记得
: 把前一本笔记簿(三张纸)的内容抄写到新笔记簿里。
: ...
: ...
: ...
: 到了学期末最後一堂,他发现他获得了一本厚达 1000 张的完美笔记,以及...
: 他曾有过的笔记簿群共 499500 张纸,记不清他用掉多少笔在抄写上,与多少劳力
: 与时间在重复抄写上。
: [傻瓜第四部曲.完]
--
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 163.29.28.131
1F:推 fptt:在执行SQL前replace掉1=1...这是我过去会用的方式...XD 04/02 13:03
2F:推 cyclone350:我们讨论他的运作原理,但是要依情况去判断该用哪种 !! 04/02 13:10
3F:→ cyclone350:也没人说一定要用 StingBuilder for all case ! 04/02 13:14
4F:→ cyclone350:就像不会有的系统参数让你设定 fast = true 一样 04/02 13:17
5F:→ swpoker:其实就是固守某个规则~缺乏变通而已 04/02 13:25
6F:→ cha122977:我觉得在依条件建立字串时 用StringBuilder也比较好读~ 04/02 16:13