淺析C#中StringBuilder類(lèi)的高效及與String的對(duì)比
在C#中,在處理字符串拼接的時(shí)候,使用StringBuilder的效率會(huì)比硬拼接字符串高很多。到底有多高,如下:
static void Main( string[] args )
{
string str1 = string.Empty;
Stopwatch sw1 = new Stopwatch();
sw1.Start();
for ( int i = 0; i < 10000; i++ )
{
str1 = str1 + i.ToString();
}
sw1.Stop();
Console.WriteLine( "拼接字符串所耗費(fèi)時(shí)間為:" + sw1.ElapsedMilliseconds + "毫秒" );
StringBuilder str2 = new StringBuilder( 10000 );
Stopwatch sw2 = new Stopwatch();
sw2.Start();
for ( int i = 0; i < 10000; i++ )
{
str2.Append( i.ToString() );
}
sw2.Stop();
Console.WriteLine( "使用StringBuilder所耗費(fèi)時(shí)間為:" + sw2.ElapsedMilliseconds + "毫秒" );
Console.ReadKey();
}
上面代碼執(zhí)行的效果如下:

string類(lèi)型的特別之處在于我們可以像使用值類(lèi)型那樣使用string類(lèi)型,而實(shí)際上string是引用類(lèi)型。既然是引用類(lèi)型,CLR就會(huì)把string類(lèi)型保存在托管堆上。當(dāng)我們使用str1 = str1 + i.ToString();進(jìn)行拼接,由于string類(lèi)型的恒定性,不會(huì)改變str1在內(nèi)存中的地址,而是在托管堆上創(chuàng)建了另外一個(gè)字符串對(duì)象。如此,拼接10000次,就創(chuàng)建了10000個(gè)string類(lèi)型對(duì)象,效率難免低下。
而StringBuilder會(huì)在內(nèi)存中開(kāi)辟一塊連續(xù)的內(nèi)存,當(dāng)增加字符串實(shí)際上是針對(duì)同一塊內(nèi)存的修改,所以效率更高。
當(dāng)然,到底使用硬拼接字符串,還是使用StringBuilder,不是絕對(duì)的,要看情況。當(dāng)拼接字符串很少的情況下,當(dāng)然直接硬拼接字符串就行了。
深入string和stringBuilder的區(qū)別
String對(duì)象是不可改變的。每次使用System.String類(lèi)中的方法之一或者是進(jìn)行運(yùn)算時(shí)(如賦值、拼接等),都要在內(nèi)存中創(chuàng)建一個(gè)新的字符串對(duì)象,這就需要為該新對(duì)象分配內(nèi)存空間,而StringBuilder則不會(huì)。在需要對(duì)字符串執(zhí)行重復(fù)修改操作時(shí),與創(chuàng)建新的 String 對(duì)象相關(guān)的系統(tǒng)開(kāi)銷(xiāo)可能會(huì)非常昂貴。如果要修改字符串而不創(chuàng)建新的對(duì)象,則可以使用 System.Text.StringBuilder 類(lèi)。例如,當(dāng)在一個(gè)循環(huán)中將許多字符串連接在一起時(shí),使用 StringBuilder 類(lèi)可以提升性能。
String類(lèi)型對(duì)象的特點(diǎn):
1.它是引用類(lèi)型,在堆上分配內(nèi)存
2.運(yùn)算時(shí)會(huì)產(chǎn)生一個(gè)新的實(shí)例
3.String 對(duì)象一旦生成不可改變(Immutable)
4.定義相等運(yùn)算符(== 和 !=)是為了比較 String 對(duì)象的值(而不是引用)
大家都知道字符串對(duì)象是”不可變的”,
對(duì)字符串進(jìn)行操作的方法實(shí)際上返回的是新的字符串對(duì)象。
在前面的示例中,將 s1 和 s2 的內(nèi)容連接起來(lái)以構(gòu)成一個(gè)字符串時(shí),包含 "orange" 和 "red" 的兩個(gè)字符串均保持不變。+= 運(yùn)算符會(huì)創(chuàng)建一個(gè)包含組合內(nèi)容的新字符串。結(jié)果是 s1 現(xiàn)在引用一個(gè)完全不同的字符串。只包含"orange" 的字符串仍然存在,但連接 s1 后將不再被引用。
大量的字符串相加的時(shí)候就會(huì)有很多想s1一樣的 不在被引用,從而造成資源的極大浪費(fèi).
大家注意這點(diǎn)
string stringValue = this.m_StringValue; internal volatile string m_StringValue;
寫(xiě)到這里,需要有人見(jiàn)看到了 volatile,也許不明白是什么意思,大概的說(shuō)下.
volatile關(guān)鍵字實(shí)現(xiàn)了線程間數(shù)據(jù)同步,用volatile修飾后的變量不允許有不同于”主”內(nèi)存區(qū)域的變量拷貝。
換句話說(shuō),一個(gè)變量經(jīng)volatile修飾后在所有線程中必須是同步的;任何線程中改變了它的值,所有其他線程立即
獲取到了相同的值。理所當(dāng)然的,volatile修飾的變量存取時(shí)比一般變量消耗的資源要多一點(diǎn),因?yàn)榫€程有它自己的
變量拷貝更為高效。
this.NeedsAllocation(stringValue, requiredLength)
只有在需要的時(shí)候才去重新分配.
就分配空間和線程的使用上來(lái)講,StringBuilder肯定比String要高,但是前提是使用頻率比較高的情況下.
相關(guān)文章
WPF?Trigger改變屬性無(wú)效問(wèn)題排查示例詳解
這篇文章主要為大家介紹了WPF?Trigger改變屬性無(wú)效問(wèn)題排查示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
unity AudioSource播放完聲音后要執(zhí)行的函數(shù)或條件操作
這篇文章主要介紹了unity AudioSource播放完聲音后要執(zhí)行的函數(shù)或條件操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
C#實(shí)現(xiàn)根據(jù)實(shí)體類(lèi)自動(dòng)創(chuàng)建數(shù)據(jù)庫(kù)表
本文主要介紹了C#通過(guò)自定義特性實(shí)現(xiàn)根據(jù)實(shí)體類(lèi)自動(dòng)創(chuàng)建數(shù)據(jù)庫(kù)表的方法。具有很好的參考價(jià)值,需要的朋友一起來(lái)看下吧2016-12-12
C# 實(shí)現(xiàn)視頻監(jiān)控系統(tǒng)(附源碼)
這篇文章主要介紹了C# 如何實(shí)現(xiàn)視頻監(jiān)控系統(tǒng),幫助大家更好的理解和使用c#,感興趣的朋友可以了解下2021-02-02
WPF實(shí)現(xiàn)自帶觸控鍵盤(pán)的文本框
這篇文章實(shí)現(xiàn)了WPF自帶觸控鍵盤(pán)的文本框,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10

