C 中如何正確的使用字串String

2022-09-26 03:18:11 字數 3250 閱讀 9775

前言

c#中提供了比較全面的字串處理方法,很多函式都進行了封裝為我們的程式設計工作提供了很大的便利。system.string是最常用的字串操作類,可以幫助開發者完成絕大部分的字串操作功能,使用方便。

字串作為所有程式語言中使用最頻繁的一種基礎資料型別。如果使用不慎,將會造成不必要的記憶體開銷,為此而付出代價。

而要優化此型別,從以下兩點入手:

1、盡量少的裝箱

2、避免分配額外的記憶體空間

先從第一點裝箱的操作說起,檢視如下**:

//發生裝箱的**

string boxoperate = "test" + 4.5f;

其中間語言il**為如下:

il_0000: nop

il_0001: ldstr "test"

il_0006: ldc.r4 4.5

il_000b: box [mscorlib]system.single

il_0010: call string [mscorlib]system.string::concat(object, object)

il_0015: stloc.0

il_0016: call valuetype [mscorlib]system.consolekeyinfo [mscorlib]system.console::readkey()

il_001b: pop

il_001c: ret

不難看出,上述**發生了裝箱的操作(il**中的box).裝箱之所以會發生效能損耗,因為它要完成如下三個步驟:

1、首先,會為值型別在託管堆中分配記憶體。除了值型別本身所分配的記憶體外,記憶體總量還要加上型別物件指標和同步塊索引所占用的記憶體,

2、將值型別的值複製到新分配的堆記憶體中。

3、返回已經程式設計客棧成為引用型別的物件的位址。

在來看以下**:

//沒有發生裝箱的**

string boxoperate = "test" + 4.tostring();

其中間il**如下:

il_0000: nop

il_0001: ldstr "test"

il_0006: ldc.r4 4

il_000b: stloc.1

il_000c: ldloca.s 1

il_000e: call instance string [mscorlib]system.single::tostring()

il_0013: call string [mscorlib]system.string::concat(string, string)

il_0018: stloc.0

il_0019: call valuetype [mscorlib]system.consolekeyinfo [mscorlib]system.console::readkey()

il_001e: pop

il_001f: ret

如上,並沒有發生任何裝箱操作,但是達到的結果卻是我們想要的。原因是 4.tostring() 這行**並沒有發生裝箱行為,是實際呼叫的是整數型的tostring()方法,其原型如下:

public override string tostring()

可能有人會問,是不是原型中的 number.format_***方法會發生裝箱行為呢?實際上,number.format_***方法是乙個非託管的方法,其原型如下:

[methodimpl(methodimploptions.internalcall), securitycritical]

public statuc extern string formatint32(int value, string format,numberformatinfo info);

它是通過直接操作記憶體來完成 int32 到 string 的轉換,效率要比裝箱高得多。所以,在使用其他值引用型別到字串得轉換比完成拼接時,應當避免使用操作符 「+」 來我完成,而應該使用值引用型別提供得tostring方法。

也許有人會問:即使fcl提供得方法沒有發生裝箱行為,但在其他情況下,fcl方法內部會不會含有裝箱的行為?也許會存在,所以,本人推薦:編寫**中,應當盡量避免發生不必要的裝箱**。

第二個方面:避免分配額外的空間。對於clr來說,string物件(字串物件)是個很特殊的物件,它一旦被賦值就不可改變(在記憶體中)。在執行時呼叫system.string類中的任何方法或進行任何運算('=『賦值,'+『拼接等),都會在記憶體中建立乙個新的字串物件,這也意味著要為該新物件分配新的記憶體空間。如以下**會帶來額外開銷。

private static void test()

而在以下**中,字串不會在執行時拼接字串,而是會在編譯時直接生成乙個字串。

private static void test()

private static void test2()

由於使用system.string類會在某些場合帶來明顯的效能損耗,所以微軟另外提供了乙個型別stringbuilder來彌補string的不足。vjihargivn

stringbuilder並不會重新建立乙個string物件,它的效率源於預先以非託管的方式分配記憶體。如果stringbuilder沒有先定義長度,則預設分配的長度為16。當stringbuilder的長度大於16小於32時,stringbuild又會重新分配記憶體,使之成為16的倍數。stringbuilder重新分配記憶體時按照上次的容量加倍進行分配的。注意:stringbuilder指定的長度要合適,太小了,需要頻繁分配記憶體;太大了,浪費記憶體空間。

以下是例子舉例:

private static string test3()

private static string test4()

//以上兩種效率都不高效。不要以為前者比後者建立的字串物件更少,事實上,兩者建立的字串物件相等

//且前者進行了3次的string.contact方法呼叫,比後者還多了兩次。

要完成上圖的執行時的字串拼接(注意:是執行時),更佳的做法是使用stringbuilder型別,**如下:

private static string test5()

微軟還提供了另外乙個來簡化這種操作,即使用string.format 方法。string.format方法在內部使用stringbuilder 進行字串格式化,如下圖**:

private static string test6()

", a, b, c, d);

}總結:

在使用string字串時,應該盡量避免裝箱操作和「+」連線操作。

本文標題: c#中如何正確的使用字串string

本文位址:

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

字串應該是所有程式語言中使用最頻繁的一種基礎資料型別。如果使用不慎,我們就會為一次字串的操作所帶來的額外效能開銷而付出代價。本條建議將從兩個方面來 如何規避這類效能開銷 1.確保盡量少的裝箱 2.避免分配額外的記憶體空間。第乙個方面 確保盡量少的裝箱 對於裝拆箱,我們應該不陌生,值型別轉換成引用型別...

python中字串(str)的操作

s hello 字串的重疊 s hello 2 字串的拼接 s hello world print s 統計字元個數 print len s 提取單個字元,通過下表提取 從開頭提取,下表從0開始 print s 0 從結尾提取,下表從 1開始 print s 1 切片 s 開始 結束 步進 s ab...

如何把字串str轉成ArrayList

string str 9935,2010 fifa世界盃 在南非 0 470393,南非,墨西哥,1.z99a,06 11 0,4,1,0 0,4697934,0,7000 5,10462942,2.800,3.050,2.590 1,10462938,1.03,0.88,0.0,0 3,10462...