objetos numeros concatenar caracteres cadenas c# .net string optimization

caracteres - concatenar numeros c#



¿La forma más eficiente de concatenar cadenas? (17)

Agregando a las otras respuestas, tenga en cuenta que a StringBuilder se le puede decir una cantidad inicial de memoria para asignar .

El parámetro de capacidad define el número máximo de caracteres que se pueden almacenar en la memoria asignada por la instancia actual. Su valor está asignado a la propiedad Capacity . Si el número de caracteres que se almacenarán en la instancia actual excede este valor de capacidad , el objeto StringBuilder asigna memoria adicional para almacenarlos.

Si la capacidad es cero, se utiliza la capacidad predeterminada específica de la implementación.

La adición repetida a un StringBuilder que no ha sido asignado previamente puede dar lugar a muchas asignaciones innecesarias, como concatenar repetidamente cadenas regulares.

Si sabe cuánto tiempo durará la cadena final, puede calcularlo de manera trivial o puede hacer una conjetura informada sobre el caso común (asignar demasiado no es necesariamente una mala cosa), debe proporcionar esta información al constructor o al Capacity propiedad. Especialmente cuando se ejecutan pruebas de rendimiento para comparar StringBuilder con otros métodos como String.Concat, que hacen lo mismo internamente. Cualquier prueba que vea en línea que no incluya la asignación previa de StringBuilder en sus comparaciones es incorrecta.

Si no puede adivinar el tamaño, es probable que esté escribiendo una función de utilidad que debería tener su propio argumento opcional para controlar la asignación previa.

¿Cuál es la forma más eficiente de concatenar cadenas?


De este artículo de MSDN :

Existe una sobrecarga asociada con la creación de un objeto StringBuilder, tanto en tiempo como en memoria. En una máquina con memoria rápida, un StringBuilder vale la pena si está realizando unas cinco operaciones. Como regla general, diría que 10 o más operaciones de cadena son una justificación de la sobrecarga en cualquier máquina, incluso una más lenta.

Por lo tanto, si confía en MSDN, vaya con StringBuilder si tiene que hacer más de 10 operaciones / concatenaciones de cadenas; de lo contrario, la cadena simple concat con ''+'' está bien.


Dependería del código. Por lo general, StringBuilder es más eficiente, pero si solo está concatenando algunas cadenas y haciendo todo en una línea, es probable que las optimizaciones de código se encarguen de usted. Es importante pensar cómo se ve el código también: para conjuntos más grandes, StringBuilder hará que sea más fácil de leer, y para los pequeños, StringBuilder solo agregará el desorden innecesario.


Desde Chinh Do - StringBuilder no siempre es más rápido :

Reglas de juego

  • Cuando concatene tres valores de cadena dinámica o menos, use la concatenación de cadena tradicional.

  • Cuando concatene más de tres valores de cadena dinámicos, use StringBuilder.

  • Al crear una cadena grande a partir de varios literales de cadena, use el literal @ cadena o el operador en línea +.

La mayoría de las veces, StringBuilder es su mejor apuesta, pero hay casos como se muestra en esa publicación que al menos debería pensar en cada situación.


El método StringBuilder.Append() es mucho mejor que usar el operador +. Pero he encontrado que, al ejecutar 1000 concatenaciones o menos, String.Join() es incluso más eficiente que StringBuilder .

StringBuilder sb = new StringBuilder(); sb.Append(someString);

El único problema con String.Join es que tiene que concatenar las cadenas con un delimitador común. (Editar :) como señaló @ryanversaw, puedes hacer la cadena delimitadora. Vacía.

string key = String.Join("_", new String[] { "Customers_Contacts", customerID, database, SessionID });


Este es el método más rápido que he desarrollado durante una década para mi aplicación de PNL a gran escala. Tengo variaciones para IEnumerable<T> y otros tipos de entrada, con y sin separadores de diferentes tipos ( Char , String ), pero aquí muestro el caso simple de concatenar todas las cadenas de una matriz en una sola cadena, sin separador. La última versión aquí está desarrollada y probada por unidades en C # 7 y .NET 4.7 .

Hay dos claves para un mayor rendimiento; El primero es pre-calcular el tamaño total exacto requerido. Este paso es trivial cuando la entrada es una matriz como se muestra aquí. Para manejar IEnumerable<T> lugar, vale la pena reunir primero las cadenas en una matriz temporal para calcular ese total (la matriz debe evitar llamar a ToString() más de una vez por elemento ya que técnicamente, dada la posibilidad de efectos secundarios, hacerlo podría cambiar la semántica esperada de una operación de ''unión de cadena'').

A continuación, dado el tamaño total de la asignación de la cadena final, el mayor incremento en el rendimiento se obtiene al construir la cadena de resultados en el lugar . Hacer esto requiere la técnica (quizás controversial) de suspender temporalmente la inmutabilidad de una nueva String que inicialmente se asigna llena de ceros. Cualquier tal controversia a un lado, sin embargo ...

... tenga en cuenta que esta es la única solución de concatenación masiva en esta página que evita por completo una ronda adicional de asignación y copia por parte del constructor String .

Código completo:

/// <summary> /// Concatenate the strings in ''rg'', none of which may be null, into a single String. /// </summary> public static unsafe String StringJoin(this String[] rg) { int i; if (rg == null || (i = rg.Length) == 0) return String.Empty; if (i == 1) return rg[0]; String s, t; int cch = 0; do cch += rg[--i].Length; while (i > 0); if (cch == 0) return String.Empty; i = rg.Length; fixed (Char* _p = (s = new String(default(Char), cch))) { Char* pDst = _p + cch; do if ((t = rg[--i]).Length > 0) fixed (Char* pSrc = t) memcpy(pDst -= t.Length, pSrc, (UIntPtr)(t.Length << 1)); while (pDst > _p); } return s; } [DllImport("MSVCR120_CLR0400", CallingConvention = CallingConvention.Cdecl)] static extern unsafe void* memcpy(void* dest, void* src, UIntPtr cb);

Debo mencionar que este código tiene una ligera modificación de lo que yo uso. En el original, llamo a la instrucción cpblk IL desde C # para hacer la copia real. Por simplicidad y portabilidad en el código aquí, lo reemplacé con P / Invoke memcpy en memcpy lugar, como puede ver. Para obtener el máximo rendimiento en x64 ( pero tal vez no en x86 ) puede usar el método cpblk en su lugar.


Hay 6 tipos de concatenaciones de cadenas:

  1. Utilizando el símbolo más ( + ).
  2. Utilizando string.Concat() .
  3. Utilizando string.Join() .
  4. Utilizando string.Format() .
  5. Utilizando string.Append() .
  6. Utilizando StringBuilder .

En un experimento, se ha demostrado que string.Concat() es la mejor manera de aproximarse si las palabras son menos de 1000 (aproximadamente) y si las palabras son más de 1000, entonces se debe usar StringBuilder .

Para más información, consulte este site .

string.Join () vs string.Concat ()

El método string.Concat aquí es equivalente a la invocación del método string.Join con un separador vacío. Agregar una cadena vacía es rápido, pero no hacerlo es incluso más rápido, por lo que el método string.Concat sería superior aquí.


La siguiente puede ser una solución alternativa más para concatenar múltiples cadenas.

String str1 = "sometext"; string str2 = "some other text"; string afterConcate = $"{str1}{str2}";

interpolación de cuerdas


Lo más eficiente es usar StringBuilder, así:

StringBuilder sb = new StringBuilder(); sb.Append("string1"); sb.Append("string2"); ...etc... String strResult = sb.ToString();

@jonezy: String.Concat está bien si tienes un par de cosas pequeñas. Pero si está concatenando megabytes de datos, es probable que su programa se estanque.


Otra solución:

Dentro del bucle, use Lista en lugar de cadena.

List<string> lst= new List<string>(); for(int i=0; i<100000; i++){ ........... lst.Add(...); } return String.Join("", lst.ToArray());;

es muy muy rapido


Para solo dos cadenas, definitivamente no desea utilizar StringBuilder. Hay un umbral por encima del cual la sobrecarga de StringBuilder es menor que la sobrecarga de asignar varias cadenas.

Entonces, para más de 2-3 cadenas, use el código de DannySmurf . De lo contrario, simplemente use el operador +.


Prueba estos 2 códigos y encontrarás la solución.

static void Main(string[] args) { StringBuilder s = new StringBuilder(); for (int i = 0; i < 10000000; i++) { s.Append( i.ToString()); } Console.Write("End"); Console.Read(); }

Vs

static void Main(string[] args) { string s = ""; for (int i = 0; i < 10000000; i++) { s += i.ToString(); } Console.Write("End"); Console.Read(); }

Encontrará que el 1er código terminará realmente rápido y la memoria estará en una buena cantidad.

El segundo código tal vez la memoria esté bien, pero tomará más tiempo ... mucho más tiempo. Entonces, si tiene una aplicación para muchos usuarios y necesita velocidad, use el 1er. Si tiene una aplicación para un usuario de corto plazo, quizás pueda usar ambas o la segunda será más "natural" para los desarrolladores.

Aclamaciones.



Si está operando en un bucle, StringBuilder es probablemente el camino a seguir; le ahorra la sobrecarga de crear nuevas cadenas con regularidad. Sin embargo, en el código que solo se ejecutará una vez, String.Concat está bien.

Sin embargo, Rico Mariani (gurú de optimización de .NET) inventó un cuestionario en el que dijo al final que, en la mayoría de los casos, recomienda String.Format.


System.String es inmutable. Cuando modificamos el valor de una variable de cadena, se asigna una nueva memoria al nuevo valor y se libera la asignación de memoria anterior. System.StringBuilder fue diseñado para tener el concepto de una cadena mutable donde se pueden realizar una variedad de operaciones sin la ubicación de memoria separada de la asignación para la cadena modificada.



Rico Mariani , el gurú del rendimiento de .NET, tenía un artículo sobre este mismo tema. No es tan simple como se podría sospechar. El consejo básico es este:

Si su patrón se ve como:

x = f1(...) + f2(...) + f3(...) + f4(...)

esa es una concat y es rápida, StringBuilder probablemente no ayude.

Si su patrón se ve como:

if (...) x += f1(...)
if (...) x += f2(...)
if (...) x += f3(...)
if (...) x += f4(...)

entonces es probable que desee StringBuilder.

Otro artículo para respaldar esta afirmación proviene de Eric Lippert, donde describe las optimizaciones realizadas en una línea + concatenaciones de manera detallada.