亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C#中如何正確的操作字符串?

2019-11-17 02:24:56
字體:
來源:轉載
供稿:網友

C#中如何正確的操作字符串?

字符串應該是所有編程語言中使用最頻繁的一種基礎數據類型。如果使用不慎,我們就會為一次字符串的操作所帶來的額外性能開銷而付出代價。本條建議將從兩個方面來探討如何規避這類性能開銷:1. 確保盡量少的裝箱2. 避免分配額外的內存空間。

第一個方面:確保盡量少的裝箱

對于裝拆箱,我們應該不陌生,值類型轉換成引用類型即為裝箱, 引用類型轉換成值類型即為拆箱。 在自己編寫的代碼中,應當盡可能的避免編寫不必要的裝箱代碼。裝箱之所以會帶來性能損耗,因為它需要完成下面三個步驟:• 首先,會為值類型在托管堆中分配內存。除了值類型本身所分配的內存外,內存總量還要加上類型對象指針和同步塊索引所占用的內存。• 然后,將值類型的值復制到新分配的堆內存中。• 最后,返回已經成為引用類型的對象的地址。

下面是一行最簡單的裝箱代碼

1 object obj = 1;

這行語句將整型常量1賦給object類型的變量obj; 眾所周知常量1是值類型,值類型是要放在棧上的,而object是引用類型,它需要放在堆上;要把值類型放在堆上就需要執行一次裝箱操作。

這行語句的IL代碼如下,請注意注釋部分說明:

.locals init ([0] object objValue) //以上三行IL表示聲明object類型的名稱為objValue的局部變量 IL_0000: nopIL_0001: ldc.i4.s 9 //表示將整型數9放到棧頂IL_0003: box [mscorlib]System.Int32 //執行IL box指令,在內存堆中申請System.Int32類型需要的堆空間IL_0008: stloc.0 //彈出堆棧上的變量,將它存儲到索引為0的局部變量中

以上就是裝箱所要執行的操作了,執行裝箱操作時不可避免的要在堆上申請內存空間,并將堆棧上的值類型數據復制到申請的堆內存空間上,這肯定是要消耗內存和cpu資源的。我們再看下拆箱操作是怎么回事:

請看下面的C#代碼:

object objValue = 4;int value = (int)objValue;

上面的兩行代碼會執行一次裝箱操作將整形數字常量4裝箱成引用類型object變量objValue;然后又執行一次拆箱操作,將存儲到堆上的引用變量objValue存儲到局部整形值類型變量value中。

同樣我們需要看下IL代碼:

.locals init ([0] object objValue,[1] int32 'value') //上面IL聲明兩個局部變量object類型的objValue和int32類型的value變量IL_0000: nopIL_0001: ldc.i4.4 //將整型數字4壓入棧IL_0002: box [mscorlib]System.Int32 //執行IL box指令,在內存堆中申請System.Int32類型需要的堆空間IL_0007: stloc.0 //彈出堆棧上的變量,將它存儲到索引為0的局部變量中IL_0008: ldloc.0//將索引為0的局部變量(即objValue變量)壓入棧IL_0009: unbox.any [mscorlib]System.Int32 //執行IL 拆箱指令unbox.any 將引用類型object轉換成System.Int32類型IL_000e: stloc.1 //將棧上的數據存儲到索引為1的局部變量即value

拆箱操作的執行過程和裝箱操作過程正好相反,是將存儲在堆上的引用類型值轉換為值類型并給值類型變量。

裝箱操作和拆箱操作是要額外耗費CPU和內存資源的。那如何避免裝箱和拆箱操作呢?有以下方法:1. 用泛型集合取代ArrayList。2. 用C#自帶的轉換方法,將值類型轉換為引用類型。下面我們看下使用泛型和不使用泛型引發裝箱拆箱的情況。1.使用非泛型集合時引發的裝箱和拆箱操作

看下面的一段代碼:

var array = new ArrayList();array.Add(1);array.Add(2);foreach (int value in array){Console.WriteLine(“value is {0}”,value);}

代碼聲明了一個ArrayList對象,向ArrayList中添加兩個數字1,2;然后使用foreach將ArrayList中的元素打印到控制臺。

在這個過程中會發生兩次裝箱操作和兩次拆箱操作,在向ArrayList中添加int類型元素時會發生裝箱,在使用foreach枚舉ArrayList中的int類型元素時會發生拆箱操作,將object類型轉換成int類型,在執行到Console.WriteLine時,還會執行兩次的裝箱操作;這一段代碼執行了6次的裝箱和拆箱操作;如果ArrayList的元素個數很多,執行裝箱拆箱的操作會更多。

你可以通過使用ILSpy之類的工具查看IL代碼的box,unbox指令查看裝箱和拆箱的過程

2. 使用泛型集合的情況

請看如下代碼:

1 var list = new List<int>();2 list.Add(1);3 list.Add(2);4 5 foreach (int value in list)6 {7 Console.WriteLine("value is {0}", value);8 }

代碼和1中的代碼的差別在于集合的類型使用了泛型的List,而非ArrayList;我們同樣可以通過查看IL代碼查看裝箱拆箱的情況,上述代碼只會在Console.WriteLine()方法時執行2次裝箱操作,不需要拆箱操作。

可以看出泛型可以避免裝箱拆箱帶來的不必要的性能消耗;當然泛型的好處不止于此,泛型還可以增加程序的可讀性,使程序更容易被復用等等。

但是我們注意到,在使用泛型集合的時候,Console.WriteLine()方法時仍然執行2次裝箱操作。能否將這兩次裝箱操作也優化掉呢?這就使用到了第二個方法,用C#自帶的轉換方法,將值類型轉換為引用類型。如下:

var list = new List<int>();list.Add(1);list.Add(2);foreach (int value in list){Console.WriteLine(string.Format("value is {0}", value.ToString()));}

再查看IL代碼時可以發現,裝箱操作已經被徹底消除了。它實際調用的是整形的ToString方法。ToString方法的原型為:

public override string ToString(){return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);}

它是通過直接操作內存來完成從int到string的轉換,效率要比裝箱高很多。所以,在使用其他值類型到字符串的轉換并完成拼接時,應當避免使用操作符“+”來完成,而應該使用值類型提供的ToString方法。

第二個方面:避免分配額外的內存空間。對CLR來說,string對象是個很特殊的對象,它一旦被賦值就不可改變。在運行時調用System.String類中的任何方法或進行任何運算(如“=”賦值,“+”拼接等),都會在內存中創建一個新的字符串對象,這也意味著要為該新對象分配新的內存空間。像下面的代碼就會帶來運行時的額外開銷。

PRivate static void Test6(){string s1 = "abc";s1 = "123" + s1 + "456"; // 以上兩行代碼創建了3個String對象,并執行了一次String.Contact方法string s2 = 9 + "456"; // 該代碼發生一次裝箱,并調用一次String.Concact方法}private static void Test7(){string s1 = "123" + "abc" + "456"; // 該代碼等效于string s1 = "123abc456"}    

由于使用String類會在某些場合帶來明顯的性能損耗,所以微軟另外提供了一個類型StringBuilder來彌補String的不足。

StringBuilder并不會重新創建一個String對象,它的效率源于預先以非托管的方式分配內存。如果StringBuilder沒有先定義長度,則默認分配的長度為16,當StringBuilder字符長度小于等于16時,StringBuilder不會重新分配內存。當StringBuilder字符長度大于16時小于32時,StringBuilder又會重新分配內存,使之成為16的倍數。在上面的代碼中,如果預先判斷字符串的長度將大于16,則可以為其設定一個更加合適的長度。微軟還提供了另外一個方法來簡化這種操作,即使用string.Format方法。string.Format方法在內部使用StringBuilder進行字符串的格式化。

private static void Test9(){string a = "t";string b = "e";string c = "s";string d = "t";StringBuilder sb = new StringBuilder();sb.Append(a);sb.Append(b);sb.Append(c);sb.Append(d);Console.WriteLine(sb.ToString());}private static void Test10(){string a = "t";string b = "e";string c = "s";string d = "t";Console.WriteLine(string.Format("{0}{1}{2}{3}", a, b, c, d));}

最后總結:如何正確操作字符串:

1. 確保盡量少的拆裝箱操作:使用泛型,使用ToString()將值類型轉換為引用類型2. 避免分配額外的內存空間:不用+=, +操作符, 使用StringBuilder, String.Format()鏈接多個String

參考引用列表:?

http://www.49028c.com/yukaizhao/archive/2011/10/18/csharp_box_unbox_1.htmlhttp://www.49028c.com/yukaizhao/archive/2011/10/19/csharp_box_unbox_2.html?《編寫高質量代碼:改善C#程序的157個建議》


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲成色999久久网站| 亚洲999一在线观看www| 色综合老司机第九色激情| www.久久色.com| 国产精品精品久久久久久| 琪琪亚洲精品午夜在线| 亚洲欧美日韩久久久久久| 亚洲精品乱码久久久久久按摩观| 欧美洲成人男女午夜视频| 欧美成人免费在线视频| 欧美丝袜美女中出在线| 91美女高潮出水| 97精品国产97久久久久久春色| 国内精品久久久| 2019亚洲日韩新视频| 日韩av一区在线| 在线播放日韩精品| 久久99国产精品久久久久久久久| 亚洲一级免费视频| 国产欧美精品久久久| 91精品国产色综合久久不卡98| 中文字幕日韩av| 久久精品视频在线| 日本一欧美一欧美一亚洲视频| 国语自产精品视频在免费| 69**夜色精品国产69乱| 欧美性色19p| 国产在线观看一区二区三区| 日本91av在线播放| 亚洲国产欧美一区二区三区久久| 国产精品欧美激情在线播放| 久久高清视频免费| 欧美老少配视频| 久久中文字幕一区| 成人a级免费视频| 成人网在线视频| 亚洲自拍另类欧美丝袜| 欧美成人午夜影院| 欧美一级电影免费在线观看| 精品久久久久久中文字幕大豆网| 亚洲成人1234| 日韩av免费在线观看| 国内精品模特av私拍在线观看| 日韩国产精品亚洲а∨天堂免| 91精品美女在线| 久久精彩免费视频| 国产亚洲xxx| 一本色道久久88亚洲综合88| 国产精品影片在线观看| 色爱av美腿丝袜综合粉嫩av| 中文字幕日韩av| 久久久国产精品视频| 精品久久久免费| 欧美视频在线看| 国产ts人妖一区二区三区| 日韩成人av网址| 久久五月情影视| 国产精品久久久久久久久借妻| 国产成人精彩在线视频九色| 亚洲性av在线| 亚洲欧美一区二区激情| 亚洲国产精品福利| 亚洲男人av在线| 中文字幕日本精品| 久久大大胆人体| 亚洲精品久久久久久久久久久| 欧美国产日韩在线| 国产精品一区二区久久| 午夜免费日韩视频| 国产一区二区三区在线免费观看| 草民午夜欧美限制a级福利片| 日韩中文字幕在线精品| 欧美中文字幕精品| 国产精品偷伦免费视频观看的| www.欧美精品一二三区| 欧美色道久久88综合亚洲精品| 97视频在线观看免费高清完整版在线观看| 国产日产欧美a一级在线| 日韩一级裸体免费视频| 97精品视频在线观看| 亚洲一区二区在线| 一夜七次郎国产精品亚洲| 精品高清美女精品国产区| 九九九久久久久久| 精品中文字幕在线2019| 高潮白浆女日韩av免费看| 国产美女主播一区| 国产精品自产拍在线观| 国产91在线高潮白浆在线观看| 日韩女优人人人人射在线视频| 国产精品久久色| 久久激情视频免费观看| 欧美成人中文字幕在线| 亚洲国产精品999| 欧美老少做受xxxx高潮| 日韩中文字幕网| 久久精品最新地址| 97精品在线视频| 亚洲在线免费观看| 欧美激情精品久久久| 日韩在线不卡视频| 欧美成在线视频| 国产日韩欧美在线观看| 欧美性xxxxxxxxx| 久久人人97超碰精品888| 欧美性猛xxx| 97香蕉超级碰碰久久免费软件| 亚洲女同性videos| 夜色77av精品影院| 亚洲国产欧美一区二区三区同亚洲| 亚洲色图第一页| 亚洲第一区第二区| 国产精品老女人视频| 国产精品久久久久久久久久久久久| www.久久久久久.com| 日韩av中文在线| 国产精品中文在线| 成人精品在线观看| 久久99久久99精品中文字幕| 欧美尤物巨大精品爽| 亚洲国产一区二区三区在线观看| 国产一区二区视频在线观看| 91嫩草在线视频| 国产精品视频久久久| 国产精品91久久久| 国产狼人综合免费视频| 国产欧美一区二区三区四区| 91精品啪在线观看麻豆免费| 97超级碰碰人国产在线观看| 欧美成人亚洲成人日韩成人| 欧美日韩一区免费| 久久久久久国产精品| 九九热精品视频| 欧美老少做受xxxx高潮| 国模gogo一区二区大胆私拍| 久久综合免费视频影院| 国内精品小视频在线观看| 久久久91精品国产一区不卡| 57pao国产精品一区| 国产一区二区三区视频免费| 韩国福利视频一区| 成人精品久久久| 亚洲毛片在线免费观看| 亚洲午夜色婷婷在线| 国产亚洲精品成人av久久ww| 日韩黄在线观看| 久久精品美女视频网站| 性欧美长视频免费观看不卡| 亚洲成人1234| 欧美亚洲第一页| 久久久精品电影| 久久人人看视频| 97国产真实伦对白精彩视频8| 欧美午夜影院在线视频| 性色av一区二区咪爱| 91九色在线视频| 高清亚洲成在人网站天堂| 欧美电影《睫毛膏》| 欧美精品电影免费在线观看| 国产精品亚发布| 国产91色在线|免| 国产成人亚洲综合| 亚洲欧洲国产一区| 亚洲四色影视在线观看|