001. 正確操作字符串


  1. 避免不必要的裝箱

自定義結構體

struct MyStruct { }

FCL,String自帶的拼接字符串方法

public static String Concat(params object[] args);

示例

string str1 = "str1" + 9 + false + new MyStruct() + new object();

等價於

string str1 = string.Concat("str1", 9, false, new MyStruct(), new object());

以上,發生3次裝箱,1次Concat

改為

string str1 = "str1" + 9.ToString() + false.ToString() + new MyStruct().ToString() + new object();

未發生裝箱,性能較高

結論:

拼接字符串時(+ 或 Concat),以 + 值類型.ToString()方式,不要以 + 值類型方式

  1. 避免分配額外的內存空間

    拼接"abc"和"123"的三種方法

    const string cs123 = "123";
    string s123 = "123";
    
    string str = "abc" + "123"; // 方法1
    str = "abc" + s123;         // 方法2
    str = "abc" + cs123;        // 方法3
    

    方法1因為都是字面值,所以編譯時相當於string str = "abc123",未調用Concat(),未分配內存空間

    方法2調用1次Concat(),分配1次內存空間

    方法3等價於方法1,因為cs123是constant字面值,在編譯期就被替換成“123”。未調用Concat(),未分配內存空間

  2. 使用StringBuilder拼接字符串

    string是不可變類型,任何修改字符串的操作都會導致開辟新的內存空間,頻繁修改字符串或拼接字符串時,使用StringBuilder更合適。

    a. StringBuilder功能表現就像是一個List

    b. 非托管方式分配內存

    c. 默認容量16,但可以指定初始容量,不夠用時就翻倍

拓展

裝箱為什么影響性能?

引入了內存開銷 + 時間開銷

步驟:

a. 開辟堆中內存:值本身 + 類型對象指針 + 同步索引塊

b. 棧中值復制到堆

c. 實例地址返回到棧中引用變量

9.ToString()

結構體調用它的方法時並不需要先裝箱。微軟為int提供的ToString()實際調用的是非委托代碼直接操作內存返回一個字符串,而非通過CLR.

String.Format()

String.Format("{0}{1}{2}{3}",a,b,c,d);
$"{a}{b}{c}{d}"

$插值法和String.Format()底層都是使用StringBuilder拼接

測試題

StringBuilder sb = new StringBuilder();
sb.Append("t");
sb.Append("e");
sb.Append("s");
sb.Append("t");

爛代碼。使用StringBuilder拼接字面值多此一舉,采用"t" + "e" + "s" + "t"形式拼接,編譯時直接是"test",內存和時間開銷最佳。

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);

好代碼。StringBuilder適合拼接運行時字符串變量。



免責聲明!

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



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