c# - texto - La forma más rápida de eliminar caracteres de la cadena
quitar puntos de un string c# (7)
Aquí está la versión insegura súper-rápida, la versión 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));
}
Y aquí están los puntos de referencia (tiempo para quitar 1000000 cadenas en ms)
cornerback84''s String.Replace: 9433 Andy West''s String.Concat: 4756 AviJ''s char array: 1374 Matt Howells'' char pointers: 1163
Tengo una cadena de la que tengo que eliminar los siguientes caracteres: ''/ r'', ''/ n'' y ''/ t''. He intentado tres formas diferentes de eliminar estos caracteres y los he evaluado para poder obtener la solución más rápida.
Los siguientes son los métodos y el tiempo de ejecución cuando los ejecuté 1000000 veces:
Debería ser la solución más rápida si tengo 1 o 2 caracteres para eliminar. Pero a medida que pongo más char, empieza a tomar más tiempo.
str = str.Replace("/r", string.Empty).Replace("/n", string.Empty).Replace("/t", string.Empty);
Tiempo de ejecución = 1695
Para 1 o 2 char, esto fue más lento que String.Replace, pero para 3 char mostró un mejor rendimiento.
string[] split = str.Split(new char[] { ''/t'', ''/r'', ''/n'' }, StringSplitOptions.None);
str = split.Aggregate<string>((str1, str2) => str1 + str2);
Tiempo de ejecución = 1030
El más lento de todos, incluso con 1 personaje. Tal vez mi expresión regular no sea la mejor.
str = Regex.Replace(str, "[/r/n/t]", string.Empty, RegexOptions.Compiled);
Tiempo de ejecución = 3500
Estas son las tres soluciones que se me ocurrieron. ¿Hay alguna solución mejor y más rápida que alguien aquí conozca, o alguna mejora que pueda hacer en este código?
Cadena que utilicé para el benchmarking:
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();
Aun más rápido:
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);
}
Creo que obtendrás el mejor rendimiento posible al componer la nueva cadena como una matriz char y solo la convertirás en una cadena cuando hayas terminado, así:
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);
EDITAR: usando String (s2, 0, i2) en lugar de Trim (), por sugerencia
Recorrer la cadena y usar (solo uno) StringBuilder (con el argumento del constructor adecuado, para evitar asignaciones de memoria innecesarias) para crear una nueva cadena podría ser más rápido.
prueba esto
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);
String.Join(null, str.Split(new char[] { ''/t'', ''/r'', ''/n'' },
StringSplitOptions.None));
podría darle un aumento de rendimiento con el uso de Aggregate()
ya que Join()
está diseñado para cadenas.
EDITAR :
En realidad, esto podría ser aún mejor:
String.Concat(str.Split(new char[] { ''/t'', ''/r'', ''/n'' },
StringSplitOptions.None));