看板 C_Sharp 關於我們 聯絡資訊
C#的string比起C或是C++方便很多, 但是操作簡單的背後隱藏著效能陷阱, 比如我在初學的時候就經常使用這樣的做法: string s; for (int i = 0; i < 10; i++) s += i.ToString(); 語法上可以過,也非常直覺, 但後來經過前輩的提點,這樣的做法會造成每次迴圈s都重複拆箱裝箱, 等於是每次都是new一個新的string出來, 其實是相當浪費效能的,能避就避,建議使用StringBuilder 現在有一個case是這樣的, float x, y; string str = ((int)(x / (x + y) * 100)).ToString() + "%"; 簡單說就是一個顯示x百分比的算式, 按照上面的拆箱裝箱的邏輯,這一行算式會進行兩次裝箱運算, 首先將(int)(x / (x + y) * 100)裝成一個string, 接著再把這個string加"%",裝成要求的str。 這行算式是否可以寫成 string str = ((int)(x / (x + y) * 100)) + "%"; 就是很單純的沒有加上.ToString() 前面的數字會被隱含轉換成string, 依然可以做成要求的數字,這樣寫法的裝箱次數又是幾次? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 1.169.41.67
fireslayer:這兩行一模一樣 03/16 16:00
ssccg:隱含轉換成string就是等於呼叫ToString 03/16 16:13
ssccg:說拆箱裝箱其實不太對,string是reference type,不是value 03/16 16:20
ssccg:type,必須每次都產生新的是因為immutable 03/16 16:21
瞭解,所以沒辦法在一行code 僅一次裝箱完成這句算式囉? ※ 編輯: stu87616 來自: 1.169.41.67 (03/16 16:28)
ssccg:只要不是(可能)次數很大的迴圈,不用去擔心這點 03/16 16:30
ssccg:C#語言設計成這樣就是這樣用的 03/16 16:30
erspicu:如果對程式執行感受毫無影響或是影響輕微可忽略 其實 03/16 17:55
erspicu:根本不需要在這種節骨眼上浪費時間進行這種小優化 03/16 17:55
andymai:仔細想想~你要的數字字串都是不一樣的~從最根本看來~並沒 03/16 20:42
andymai:有辦法解決new string不是嗎?除非能再想到另一種方法組出 03/16 20:43
andymai:你要的數字字串~但效能會好上多少~是否值得也是問題... 03/16 20:44
songting:如果你是一次要轉檔上萬筆資料 用tostring的確不太好 03/16 21:47
我想到因為百分比一定在0~100%之間, 而我這個case又剛好只要整數, 所以可以先做一個string[101]把所有的資料都存好, 然後根據數值引用陣列,這樣值不值得呢~? 我也知道這種小細節不必太計較, 就算是上萬筆的資料,也頂多就是幾秒或幾十秒的差別罷了, 只是我就是想知道有沒有存在最佳的做法 ※ 編輯: stu87616 來自: 1.169.41.67 (03/16 23:50)
andymai:就算可以~這種做法也是用"空間"換取時間~若是大型程式~又 03/17 06:22
andymai:要考慮是否空間夠用~以及是否一直存在~還是會消失~如果這 03/17 06:24
andymai:個案例不是單純101個短字串~那又可能會造成空間拖到時間XD 03/17 06:25
erspicu:你可以用stopwatch做BENCHMARK測試 以10萬比來說 03/17 09:01
erspicu:我猜兩者差異是0.X秒的等級 03/17 09:18
erspicu:如果你的編譯器選項有開優化 差異應該會更小 03/17 09:19
erspicu:實際上如果對這塊領域有興趣 應該要學clr中介碼 03/17 09:45
erspicu:把程式反組譯後看看編譯器實際生成內碼為何 03/17 09:46
erspicu:否則很容易淪為空想和猜測 一些以為更快的非通例做法結果 03/17 09:47
erspicu:到頭來甚至有可能會更慢 03/17 09:47
ssccg:小整數我想.NET本來就有作優化,不用你自己作 03/17 14:32