2010-02-02 75 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