从字符串中删除字符的最快方法

我有一个字符串,我必须从中删除以下字符:’\ r’,’\ n’和’\ t’。 我尝试了三种不同的方法来删除这些字符并对它们进行基准测试,以便我可以获得最快的解决方案。

以下是我运行1000000次的方法和执行时间:

如果我要删除1或2个字符,它应该是最快的解决方案。 但随着我投入更多的焦炭,它开始花费更多的时间

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

执行时间= 1695

对于1或2个char,这比String.Replace慢,但是对于3个char它表现出更好的性能。

 string[] split = str.Split(new char[] { '\t', '\r', '\n' }, StringSplitOptions.None); str = split.Aggregate((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(); 

这是超快速的不安全版本,版本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)); } 

以下是基准测试(以ms为单位剥离1000000个字符串的时间)

  cornerback84的String.Replace:9433
     Andy West的String.Concat:4756
     AviJ的char数组:1374
     Matt Howells的焦点指针:1163 

我相信通过将新字符串组合为char数组并在完成后将其转换为字符串,您将获得最佳性能,如下所示:

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

编辑:根据建议使用String(s2,0,i2)而不是Trim()

循环遍历字符串并使用(只有一个)StringBuilder(使用正确的构造函数参数,以避免不必要的内存分配)来创建新字符串可能会更快。

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

可能会比使用Aggregate()提高性能,因为Join()是为字符串设计的。

编辑

实际上,这可能会更好:

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

甚至更快:

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

试试这个

 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()); 
 string str; str = str.Replace(Environment.NewLine, string.Empty).Replace("\t", string.Empty);