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

看板java作者 (swpoker)時間11年前 (2013/04/02 12:03), 編輯推噓2(204)
留言6則, 4人參與, 最新討論串7/8 (看更多)
這個我在系統最常見的範例就是 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

04/02 13:03, , 1F
在執行SQL前replace掉1=1...這是我過去會用的方式...XD
04/02 13:03, 1F

04/02 13:10, , 2F
我們討論他的運作原理,但是要依情況去判斷該用哪種 !!
04/02 13:10, 2F

04/02 13:14, , 3F
也沒人說一定要用 StingBuilder for all case !
04/02 13:14, 3F

04/02 13:17, , 4F
就像不會有的系統參數讓你設定 fast = true 一樣
04/02 13:17, 4F

04/02 13:25, , 5F
其實就是固守某個規則~缺乏變通而已
04/02 13:25, 5F

04/02 16:13, , 6F
我覺得在依條件建立字串時 用StringBuilder也比較好讀~
04/02 16:13, 6F
文章代碼(AID): #1HMbYIGn (java)
討論串 (同標題文章)
文章代碼(AID): #1HMbYIGn (java)