[問題] string封裝的效能問題

看板C_Sharp作者 (DoubleLight)時間11年前 (2013/03/16 15:09), 編輯推噓0(0023)
留言23則, 5人參與, 最新討論串1/2 (看更多)
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

03/16 16:00, , 1F
這兩行一模一樣
03/16 16:00, 1F

03/16 16:13, , 2F
隱含轉換成string就是等於呼叫ToString
03/16 16:13, 2F

03/16 16:20, , 3F
說拆箱裝箱其實不太對,string是reference type,不是value
03/16 16:20, 3F

03/16 16:21, , 4F
type,必須每次都產生新的是因為immutable
03/16 16:21, 4F
瞭解,所以沒辦法在一行code 僅一次裝箱完成這句算式囉? ※ 編輯: stu87616 來自: 1.169.41.67 (03/16 16:28)

03/16 16:30, , 5F
只要不是(可能)次數很大的迴圈,不用去擔心這點
03/16 16:30, 5F

03/16 16:30, , 6F
C#語言設計成這樣就是這樣用的
03/16 16:30, 6F

03/16 17:55, , 7F
如果對程式執行感受毫無影響或是影響輕微可忽略 其實
03/16 17:55, 7F

03/16 17:55, , 8F
根本不需要在這種節骨眼上浪費時間進行這種小優化
03/16 17:55, 8F

03/16 20:42, , 9F
仔細想想~你要的數字字串都是不一樣的~從最根本看來~並沒
03/16 20:42, 9F

03/16 20:43, , 10F
有辦法解決new string不是嗎?除非能再想到另一種方法組出
03/16 20:43, 10F

03/16 20:44, , 11F
你要的數字字串~但效能會好上多少~是否值得也是問題...
03/16 20:44, 11F

03/16 21:47, , 12F
如果你是一次要轉檔上萬筆資料 用tostring的確不太好
03/16 21:47, 12F
我想到因為百分比一定在0~100%之間, 而我這個case又剛好只要整數, 所以可以先做一個string[101]把所有的資料都存好, 然後根據數值引用陣列,這樣值不值得呢~? 我也知道這種小細節不必太計較, 就算是上萬筆的資料,也頂多就是幾秒或幾十秒的差別罷了, 只是我就是想知道有沒有存在最佳的做法 ※ 編輯: stu87616 來自: 1.169.41.67 (03/16 23:50)

03/17 06:22, , 13F
就算可以~這種做法也是用"空間"換取時間~若是大型程式~又
03/17 06:22, 13F

03/17 06:24, , 14F
要考慮是否空間夠用~以及是否一直存在~還是會消失~如果這
03/17 06:24, 14F

03/17 06:25, , 15F
個案例不是單純101個短字串~那又可能會造成空間拖到時間XD
03/17 06:25, 15F

03/17 09:01, , 16F
你可以用stopwatch做BENCHMARK測試 以10萬比來說
03/17 09:01, 16F

03/17 09:18, , 17F
我猜兩者差異是0.X秒的等級
03/17 09:18, 17F

03/17 09:19, , 18F
如果你的編譯器選項有開優化 差異應該會更小
03/17 09:19, 18F

03/17 09:45, , 19F
實際上如果對這塊領域有興趣 應該要學clr中介碼
03/17 09:45, 19F

03/17 09:46, , 20F
把程式反組譯後看看編譯器實際生成內碼為何
03/17 09:46, 20F

03/17 09:47, , 21F
否則很容易淪為空想和猜測 一些以為更快的非通例做法結果
03/17 09:47, 21F

03/17 09:47, , 22F
到頭來甚至有可能會更慢
03/17 09:47, 22F

03/17 14:32, , 23F
小整數我想.NET本來就有作優化,不用你自己作
03/17 14:32, 23F
文章代碼(AID): #1HH1gN3- (C_Sharp)
文章代碼(AID): #1HH1gN3- (C_Sharp)