作者stu87616 (DoubleLight)
看板C_Sharp
標題[問題] string封裝的效能問題
時間Sat Mar 16 15:09:06 2013
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
1F:→ fireslayer:這兩行一模一樣 03/16 16:00
2F:→ ssccg:隱含轉換成string就是等於呼叫ToString 03/16 16:13
3F:→ ssccg:說拆箱裝箱其實不太對,string是reference type,不是value 03/16 16:20
4F:→ ssccg:type,必須每次都產生新的是因為immutable 03/16 16:21
瞭解,所以沒辦法在一行code 僅一次裝箱完成這句算式囉?
※ 編輯: stu87616 來自: 1.169.41.67 (03/16 16:28)
5F:→ ssccg:只要不是(可能)次數很大的迴圈,不用去擔心這點 03/16 16:30
6F:→ ssccg:C#語言設計成這樣就是這樣用的 03/16 16:30
7F:→ erspicu:如果對程式執行感受毫無影響或是影響輕微可忽略 其實 03/16 17:55
8F:→ erspicu:根本不需要在這種節骨眼上浪費時間進行這種小優化 03/16 17:55
9F:→ andymai:仔細想想~你要的數字字串都是不一樣的~從最根本看來~並沒 03/16 20:42
10F:→ andymai:有辦法解決new string不是嗎?除非能再想到另一種方法組出 03/16 20:43
11F:→ andymai:你要的數字字串~但效能會好上多少~是否值得也是問題... 03/16 20:44
12F:→ songting:如果你是一次要轉檔上萬筆資料 用tostring的確不太好 03/16 21:47
我想到因為百分比一定在0~100%之間,
而我這個case又剛好只要整數,
所以可以先做一個string[101]把所有的資料都存好,
然後根據數值引用陣列,這樣值不值得呢~?
我也知道這種小細節不必太計較,
就算是上萬筆的資料,也頂多就是幾秒或幾十秒的差別罷了,
只是我就是想知道有沒有存在最佳的做法
※ 編輯: stu87616 來自: 1.169.41.67 (03/16 23:50)
13F:→ andymai:就算可以~這種做法也是用"空間"換取時間~若是大型程式~又 03/17 06:22
14F:→ andymai:要考慮是否空間夠用~以及是否一直存在~還是會消失~如果這 03/17 06:24
15F:→ andymai:個案例不是單純101個短字串~那又可能會造成空間拖到時間XD 03/17 06:25
16F:→ erspicu:你可以用stopwatch做BENCHMARK測試 以10萬比來說 03/17 09:01
17F:→ erspicu:我猜兩者差異是0.X秒的等級 03/17 09:18
18F:→ erspicu:如果你的編譯器選項有開優化 差異應該會更小 03/17 09:19
19F:→ erspicu:實際上如果對這塊領域有興趣 應該要學clr中介碼 03/17 09:45
20F:→ erspicu:把程式反組譯後看看編譯器實際生成內碼為何 03/17 09:46
21F:→ erspicu:否則很容易淪為空想和猜測 一些以為更快的非通例做法結果 03/17 09:47
22F:→ erspicu:到頭來甚至有可能會更慢 03/17 09:47
23F:→ ssccg:小整數我想.NET本來就有作優化,不用你自己作 03/17 14:32