C# 拼接字符串的幾種方式和性能


 

開發過程中常用到的拼接字符串的方法有四種:

一般來講,拼接速度:4>>3>2>1,即方法4遠快於方法3,方法3略快於方法2,方法2略快於方法1

  1. 簡單 “+=” 拼接法

    

1
2
3
4
5
string  str= "a" ;
 
str+= "c" + "d" ;
 
string  str_1= "a" + "b" ;

  

  首先需要明白的是string類型,string是引用類型,保留在堆上,而不是棧上,用的時候傳的是內存中的地址,每次修改就會重新創建一個新的string對象來存儲字符串,原有的會被自動回收。

  第一種方式的實現原理,第一步先在內存中分配空間,存儲str變量的對象,值為"a", “+=”時,又會重新創建一個對象來存儲新的字符串(“abc"),把str指向這個新的地址。所以只有簡單幾步的拼寫時,一般不會有太大問題,如果有時候需要循環拼接時,就會不斷創建新的對象,很浪費性能和內存。

  2. String.Format()

 

1
string  str= String.Format( "{0}{1}{2}" , "a" , "b" , "c" );

  

  這就需要先看看他的源代碼了,

1
2
3
4
5
6
7
public  static  String Format(IFormatProvider provider, String format,  params  Object[] args) <br>{
     if  (format ==  null  || args ==  null )
       throw  new  ArgumentNullException((format== null )? "format" : "args" );
    StringBuilder sb =  new  StringBuilder(format.Length + args.Length * 8);
    sb.AppendFormat(provider,format,args);
     return  sb.ToString();
}

  可以看到是先創建一個StringBuilder類型的變量,長度為第一個參數的長度+參數長度的8倍。.Net自動分配一個比較大的容量來存儲。StringBuilder的介紹請看第4種方法.

  這種方式的代碼看起來比較整潔,易於閱讀,效率也比+=高效很多。

 

3.string.concat()方法:
concat源代碼:

public String concat(String str) {
  // 追加的字符串長度
  int otherLen = str.length();
  // 如果追加的字符串長度為0,則不做修改,直接返回原字符串
  if (otherLen == 0) {
  return this;
  }
  // 獲取原字符串的字符數組value的長度
  int len = value.length;
  // 將原字符串的字符數組value放到buf字符數組中
  char buf[] = Arrays.copyOf(value, len + otherLen);
  // 將追加的字符串轉化成字符數組,添加到buf中
  str.getChars(buf, len);
  // 產生一個新的字符串並返回
  return new String(buf, true);
}

  



整體是一個數組的拷貝,雖然在內存中是處理都是原子性操作,速度非常快,但是,最后的return語句創建一個新String對象,也就是每次concat操作都會創建一個新的String對象,這也是限制concat方法速度的原因。

 

4. StringBuilder.Append()

 

1
2
3
StringBuilder str= new  StringBuilder();
 
str.Append( "a" );

  

   StringBuilder 是預先創建一個比較大的內存,以后每次操作時判斷容量上限是否不夠用,如果不夠用就自動把容量擴大一倍,修改的還是第一次創建的對象的值。

 

append()方法
append源代碼:

public AbstractStringBuilder append(String str) {
// 如果是null值,則把null作為字符串處理
if (str == null)
return appendNull();
int len = str.length();
// 追加后的字符數組長度是否超過當前值
ensureCapacityInternal(count + len);
// 字符串復制到目標數組
str.getChars(0, len, value, count);
count += len;
return this;
}
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity); // 加長,並作數組拷貝
}

  



整個append方法都在做字符數組的處理,加長,拷貝等,這些都是基本的數據處理,整個方法內並沒有生成對象。只是最后toString返回一個對象而已。需要注意的是,append()方法返回的是一個StringBuilder(or StringBuffer)對象實例。

如果是簡單的拼寫時,可以用 "+=", string.format()

循環內拼寫很長的字符串時,就需要用到StringBuilder來節省性能和內存了。 - -


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM