2013-07-01 24 views
2

我想知道當我選擇將一個字符字符串或單個字符添加到常量字符串時是否會有任何性能影響。將字符串和字符串放在一起的性能

所以我寫了一個小的控制檯應用程序(.NET 4)

static class Program 
{ 
    const string STR = "string "; 

    static void Main() 
    { 
     var arr = new string[99999999]; 

     Stopwatch timer = new Stopwatch(); 

     Console.ReadLine(); 

     timer.Start(); 

     //for (uint i = 0; i < 99999999; i++) 
     //{ 
     // arr[i] = STR + 'C'; 
     //} 

     for (uint i = 0; i < 99999999; i++) 
     { 
      arr[i] = STR + "C"; 
     } 

     timer.Stop(); 

     Console.WriteLine(timer.ElapsedMilliseconds); 

     Console.ReadLine(); 
    } 
} 

你要評論一個for循環。

因此,STR + "C"大約需要1300毫秒。

對於STR + 'C'我還沒有看到結果。它需要很長時間,似乎很難打擾我的電腦。

所以,我的問題是。這種性能影響可能如何?我知道在實際使用中99999999的數值不會經常出現,但它仍然是一個巨大的差異。

在此先感謝!

回答

6

這實際上很容易解釋:你已經偶然發現了C#編譯器將對字符串表達式執行不斷摺疊的事實。

由於您聲明STRconst,因此會將其引用替換爲文字字符串"string "。然後,當編譯器遇到"string " + "C"時,它將用相應的"string C"替換該表達式。因此,實際完成的循環將花費所有時間將該字符串分配給數組中的不同位置。

相反,char串聯是優化的方式,讓你居然要等兩個級聯(包括新string對象的分配)和數組賦值。此外,該循環將生成垃圾,因此您也在等待收集器。

如果你想將兩種操作還算比較,我會做兩件事情:

  1. 變化STR的聲明static readonly,而不是const
  2. 減少迭代次數,以便實際獲得完整的運行。
+0

非常感謝,很好的回答!即使沒有恆定的「STR +」,C「」幾乎是添加字符的兩倍。所以我現在會使用單個字符串。再次感謝! – Andy

+0

@Andy很高興幫助。您的觀察是有意義的,因爲'string's可以直接連接,而不必先將'char'轉換爲'string'。 – dlev

+0

@Andy與Tigran的答案相結合:''''操作符被C#編譯器替換爲'String.Concat'的調用。當你使用字符串時,它可以直接調用接受字符串參數的重載。當你用char來使用它的時候,它必須把char放在盒子裏,並調用接受一個Object參數的重載。拳擊和拆箱操作相對昂貴,尤其是在緊密環路中執行時。但要小心,這是微觀優化的最高點! –

4

簡單的程序是這樣的:

var val = "hello ";  
val += 'r'; 

執行char值來object拳擊,這是我們可以從產生IL

IL_0001: ldstr  "hello " 
IL_0006: stloc.0  // val 
IL_0007: ldloc.0  // val 
IL_0008: ldc.i4.s 72 
IL_000A: box   System.Char 
IL_000F: call  System.String.Concat 
IL_0014: stloc.0  // val 
IL_0015: ldloc.0  // val 

而是在string情況看,沒有任何涉及拳擊,所以它顯着更快。

那麼爲什麼拳擊被執行?因爲調用System.String.Concat(String,String)(這是binary +運算符調用的結果)上有兩個參數,其中只有一個參數是string,調用過載String.Concat(object,object),所以char的值被裝箱以便能夠傳入該方法調用。

+1

你忘了解釋*爲什麼char是盒裝的,但字符串不是。 –

+0

@CodyGray:編輯我的帖子。 – Tigran

相關問題