Concatenación de cadenas frente a String Builder. Actuación

Tengo una situación en la que necesito concatenar varias cadenas para formar una identificación de una clase. Básicamente estoy haciendo un bucle en una lista para obtener los valores ToString de los objetos y luego concatenarlos.

foreach (MyObject o in myList) result += o.ToString(); 

No se espera que la lista tenga más de 5 elementos (aunque podría ser un caso muy, pero muy marginal) y generalmente tendrá de 1 a 3 elementos, siendo común que solo tenga uno o dos.

¿Qué sería más rendimiento, mantener la concatenación o usar un StringBuilder?

 StringBuilder bld = new StringBuilder() foreach (MyObject o in myList) bld.Append(o.ToString()); 

No estoy seguro si la creación de StringBuilder llevará más tiempo que la concatenación estándar para el caso más habitual.

Esto es flojo, los elementos en la lista no cambian una vez creados, por lo que la identificación se construye de forma perezosa una vez cuando se llama.

Como nota al margen … ¿Debería usar una matriz fija en lugar de una Lista? ¿Obtendré algún rendimiento o mejora de la memoria si lo hago? (La lista solo se usa como un IEnumerable de todos modos)

Una visión más general de la pregunta podría ser: ¿cuántas cadenas son suficientes para detener la concatenación y comenzar a construir?

¿Debería siquiera molestarme en probar el caso?

 if (myList.Count > 4) ConcatWithStringBuilder(myList); 

La respuesta habitual es que la concatenación de cadenas es más eficiente para entre 4 y 8 cadenas. Depende de qué blog lees.

No escriba una prueba para decidir qué método usar. Si no está seguro de si rebasará el límite mágico, simplemente use StringBuilder.

Ejecute este código para ver los resultados usted mismo:

 const int sLen=30, Loops=5000; DateTime sTime, eTime; int i; string sSource = new String('X', sLen); string sDest = ""; // // Time string concatenation. // sTime = DateTime.Now; for(i=0;i 

Árbitro. http://support.microsoft.com/kb/306822

Apoyo la idea de mantener las cosas simples hasta que tenga una buena razón para hacerlas complejas.

Para algo así como 2-5 elementos no tiene sentido usar StringBuilder (a menos que repita esta concatenación continuamente). La syntax mejor legible “+ =” tiene más valor.

Una visión más general de la pregunta podría ser: ¿cuántas cadenas son suficientes para detener la concatenación y comenzar a construir?

Esto depende de la longitud de las cadenas y si puede predecir la longitud del objective , debe proporcionar la longitud al constructor StringBuilder y si las concatena todas de una vez o en varios pasos.

Si los concatenas de una vez (como s = "A" + "b" + "c" + "d" ) entonces usar StringBuilder probablemente nunca tenga sentido.

Si puede predecir exactamente la longitud, incluso para 3 cadenas, StringBuilder sería más rápido.

Por lo general, StringBuilder es más rápido si tienes más de 5 concats. Pero incluso entonces simplemente concatenar las cuerdas generalmente tiene poca sobrecarga (a menos que se ejecute en un bucle cerrado).

Tan pronto como scopes 10 concats usando StringBuilder probablemente será favorable.

Editar: Para dejarlo en claro: en su caso, claramente debería ir sin StringBuilder .

¿Por qué no puedes simplemente usar

 String.Concat(myList) 

en lugar de reinventar la rueda? Tiene un alto rendimiento y, sin embargo, es muy simple.
Más información aquí: http://msdn.microsoft.com/en-us/library/system.string.concat.aspx

La concatenación de cadenas IMO es más legible. Usas + y + = en lugar de strBldInstance.Add () lo que puede enturbiar el código un poco más,

StringBuilder existe para hacer que la concatenación sea más efectiva, mucho más, pero generalmente sacrifico una pizca de rendimiento para la legibilidad del código. Su código no se verá afectado si usa algunas cuerdas aquí y allá. Y para ese bloque de código que hace cat muchas cadenas a menudo, use StringBuilder.

Si puede estimar el número de bytes que se utilizarán para la cadena completa (y usar esto para inicializar la capacidad del StringBuilder), es probable que StringBuilder supere a la clase String cuando hace más de aproximadamente 3 concatetos.

Es probable que el generador de cadenas sea marginalmente más rápido en este caso, pero realmente no será suficiente para preocuparse. Realmente va a depender de dos cosas, la cantidad de veces que está recreando la cadena (porque las cadenas son inmutables y la unión obliga a crear una nueva cadena a partir de las dos existentes), y el tamaño de los elementos de cadena que se concatenan juntos. Concatenar cinco cadenas de 2 bytes cada una va a ser muy diferente de concatenar 5 cadenas juntas que son 5000 bytes cada una, porque cuanto más larga es la cadena, más trabajo debe hacer el sistema para asignar memoria y recoger objetos que no son basura. más tiempo en uso. El generador de cadenas es una mejor apuesta, porque ya se ha optimizado para unir cadenas, y realmente no tienes que preocuparte por consideraciones de rendimiento.

Con todo esto en mente, si conoce el tamaño final de la cadena, el creador de cadenas seguramente será más rápido. Cuando le diga cuánta memoria asignar para la cadena final, no tendrá que pasar por el proceso de reasignar la memoria.

Usaría StringBuilder solo porque quieres ser coherente en una aplicación. La instanciación de un objeto Java / .NET tampoco consume mucho tiempo, aunque supongo que habrá algún servicio de limpieza en la configuración de StringBuilder. No es mucho peor que crear múltiples objetos String a través de la concatenación seguramente.

Si puede, podría divertirse y deshacerse del ciclo for por completo y usar aggregate?

 var concatstring = mylist.Aggregate("", (acc, item) => acc + "." + item); 

no estoy seguro en la parte superior de esto sin embargo?