Самый быстрый способ удаления символов из строки
У меня есть строка, из которой я должен удалить следующие char: '\ r', '\n' и '\ t'.
Я пробовал три разных способа удаления этих char и сравнивал их, чтобы получить самое быстрое решение.
Ниже приведены методы и время выполнения, когда я запускал их 1000000 раз:
Это должно быть самое быстрое решение, если у меня есть 1 или 2 char для удаления. Но по мере того как я добавляю больше char, он начинает занимать больше времени
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<string>((str1, str2) => str1 + str2);
Время выполнения = 1030
Самый медленный из всех, даже с 1 char. Возможно, мое регулярное выражение не лучшее.
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();
Ответы
Ответ 1
Здесь uber-fast небезопасная версия, версия 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));
}
И вот тесты (время, чтобы удалить 1000000 строк в мс)
cornerback84 String.Replace: 9433
Andy West String.Concat: 4756
AviJ char array: 1374
Matt Howells' char pointers: 1163
Ответ 2
Я считаю, что вы получите максимально возможную производительность, составив новую строку в качестве массива 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);
EDIT:, используя String (s2, 0, i2) вместо Trim(), за предложение
Ответ 3
Цитирование через строку и использование (только один) StringBuilder (с соответствующим аргументом конструктора, чтобы избежать ненужных распределений памяти) для создания новой строки может быть быстрее.
Ответ 4
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));
Ответ 5
Еще быстрее:
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);
}
Ответ 6
попробуйте это
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());
Ответ 7
string str;
str = str.Replace(Environment.NewLine, string.Empty).Replace("\t", string.Empty);