2010-02-02 74 views
18

我有一個字符串,我必須刪除以下字符:'\ r','\ n'和'\ t'。 我嘗試了三種不同的方式去除這些字符並對它們進行基準測試,以便我可以獲得最快的解決方案。從字符串中刪除字符的最快方法

以下是方法和執行有時間的時候我跑了他們100萬倍:

它應該是最快的解決方案,如果我有1個或2個字符刪除。但正如我投入更多的焦炭,它開始花費更多的時間

str = str.Replace("\r", string.Empty).Replace("\n", string.Empty).Replace("\t", string.Empty); 

執行時間= 1695

對於1或2個字符,這是慢然後與string.replace,但對於3炭它表現更好。

string[] split = str.Split(new char[] { '\t', '\r', '\n' }, StringSplitOptions.None); 
str = split.Aggregate<string>((str1, str2) => str1 + str2); 

執行時間= 1030

最慢的是,即使有1個炭。也許我的正則表達式不是最好的。

str = Regex.Replace(str, "[\r\n\t]", string.Empty, RegexOptions.Compiled); 

執行時間= 3500

這是三個解決方案,我想出了。有沒有更好更快的解決方案讓任何人知道,或者我可以在這個代碼中做什麼改進?

字符串,我用基準測試:

StringBuilder builder = new StringBuilder(); 
     builder.AppendFormat("{0}\r\n{1}\t\t\t\r\n{2}\t\r\n{3}\r\n{4}\t\t\r\n{5}\r\n{6}\r\n{7}\r\n{8}\r\n{9}", 
     "SELECT ", 
     "[Extent1].[CustomerID] AS [CustomerID], ", 
     "[Extent1].[NameStyle] AS [NameStyle], ", 
     "[Extent1].[Title] AS [Title], ", 
      "[Extent1].[FirstName] AS [FirstName], ", 
      "[Extent1].[MiddleName] AS [MiddleName], ", 
      "[Extent1].[LastName] AS [LastName], ", 
      "[Extent1].[Suffix] AS [Suffix], ", 
      "[Extent1].[CompanyName] AS [CompanyName], ", 
      "[Extent1].[SalesPerson] AS [SalesPerson], "); 
     string str = builder.ToString(); 

回答

16

這是超高速的不安全版本,版本2。

public static unsafe string StripTabsAndNewlines(string s) 
    { 
     int len = s.Length; 
     char* newChars = stackalloc char[len]; 
     char* currentChar = newChars; 

     for (int i = 0; i < len; ++i) 
     { 
      char c = s[i]; 
      switch (c) 
      { 
       case '\r': 
       case '\n': 
       case '\t': 
        continue; 
       default: 
        *currentChar++ = c; 
        break; 
      } 
     } 
     return new string(newChars, 0, (int)(currentChar - newChars)); 
    } 

這裏是基準(時間以毫秒爲單位剝離百萬字符串)

 cornerback84's String.Replace:   9433 
    Andy West's String.Concat:    4756 
    AviJ's char array:      1374 
    Matt Howells' char pointers:   1163
+1

是的。執行時間= 195 – ata 2010-02-02 11:38:04

+3

順便說一句,你需要一臺新機器:P – ata 2010-02-03 07:24:17

+1

這是一個最近的Xeon - 可能我們的基準測試只是設置不同。 – 2010-02-03 08:29:49

2

通過串循環使用(只有一個)的StringBuilder(與適當的構造函數的參數,以避免不必要的內存分配),以創建一個新的字符串可以快點。

2
String.Join(null, str.Split(new char[] { '\t', '\r', '\n' }, 
    StringSplitOptions.None)); 

可能會給你的性能提升了使用自Join()Aggregate()是專爲字符串。

編輯

其實,這可能是更好的:

String.Concat(str.Split(new char[] { '\t', '\r', '\n' }, 
    StringSplitOptions.None)); 
+0

Executio n time = 754。謝謝 – ata 2010-02-02 07:48:42

+0

不錯!我更新了我的答案以代替Concat()。也許值得嘗試一下。 – 2010-02-02 08:11:38

+0

使用String.Concat時略有改進。 現在,執行時間= 734 – ata 2010-02-02 09:15:32

8

我相信你會通過合成新的字符串作爲字符數組獲得最好的性能,只把它轉換爲字符串時,即可大功告成,就像這樣:

string s = "abc"; 
int len = s.Length; 
char[] s2 = new char[len]; 
int i2 = 0; 
for (int i = 0; i < len; i++) 
{ 
    char c = s[i]; 
    if (c != '\r' && c != '\n' && c != '\t') 
     s2[i2++] = c; 
} 
return new String(s2, 0, i2); 

編輯:使用字符串(S2, 0,i2)而不是修剪(),每個建議

+0

一個更正,你必須返回新的String(s2).TrimEnd('\ 0'); 和執行時間= 309。很好 – ata 2010-02-02 09:19:01

+2

Infact我做了一些修改。您已經保留了新陣列的長度,即i2。所以,而不是修剪,你可以使用返回新的字符串(s2,0,i2);這將執行時間帶到255 – ata 2010-02-02 09:30:29

1

試試這個

string str = "something \tis \nbetter than nothing"; 
string removeChars = new String(new Char[]{'\n', '\t'}); 
string newStr = new string(str.ToCharArray().Where(c => !removeChars.Contains(c)).ToArray()); 
+3

執行時間= 27020. – ata 2010-02-02 11:18:19

+1

LINQ是魔鬼的工作! – 2010-02-02 13:05:36

0
string str; 
str = str.Replace(Environment.NewLine, string.Empty).Replace("\t", string.Empty); 
+1

這與接受的答案中的SLOW版本沒有區別。 OP是要求最快的。 – 2012-10-19 21:34:16

2

甚至更​​快:

public static string RemoveMultipleWhiteSpaces(string s) 
    { 
     char[] sResultChars = new char[s.Length]; 

     bool isWhiteSpace = false; 
     int sResultCharsIndex = 0; 

     for (int i = 0; i < s.Length; i++) 
     { 
      if (s[i] == ' ') 
      { 
       if (!isWhiteSpace) 
       { 
        sResultChars[sResultCharsIndex] = s[i]; 
        sResultCharsIndex++; 
        isWhiteSpace = true; 
       } 
      } 
      else 
      { 
       sResultChars[sResultCharsIndex] = s[i]; 
       sResultCharsIndex++; 
       isWhiteSpace = false; 
      } 
     } 

     return new string(sResultChars, 0, sResultCharsIndex); 
    } 
+0

你有任何基準嗎? – Julian 2013-12-03 18:08:05