StringBuilder no es necesariamente más rápido. Según recuerdo, si concatena menos de una docena de cadenas, la concatenación de cadenas (ya sea a través de String.Concat o simple str1 + str2) es realmente más rápida. La razón es que la asignación e inicialización de StringBuilder en realidad lleva tiempo.
La razón por la que StringBuilder es más rápido es que crea un búfer interno al que agrega cadenas. Si está concatenando 20 cadenas, StringBuilder simplemente agrega una después de otra a su buffer y finalmente devuelve el resultado cuando se le solicita - a través de su método ToString(). (Supongo que hay suficiente espacio en el búfer. De lo contrario, a StringBuilder le preocupa volver a asignar el búfer y tiene heurística para ayudarlo a no volver a asignar demasiadas veces.) Si concatenara cadenas, cada cadena concat asignaría una nueva cadena de caracteres length (str1.Length + str2.Length) y copie la primera y la segunda cadena en su lugar. Esto da como resultado una gran cantidad de copias de cadenas.
var result = str1 + str2 + str3 + ... + strN;
Esto requerirá N-1 asignaciones y N-1 operaciones de copia. Esto puede ser muy costoso para N grande. Además, tenga en cuenta que está copiando el contenido de str1 N-1 veces. Una vez para obtener el resultado de str1 + str2. Luego nuevamente para obtener el resultado de (str1 + str2) + str3. Con StringBuilder, cada cadena se copia en el búfer interno solo una vez, suponiendo que el búfer es lo suficientemente grande para contener las cadenas individuales.
Creo que las primeras oraciones de su párrafo de cierre son incorrectas. Una línea única que concatene muchas cadenas de esta manera se compilará, a menos que esté equivocado, con una sola llamada 'string.Concat', que asigna exactamente el espacio suficiente para la cadena resultante una vez, sin necesidad de realizar varias reasignaciones como usted sugiere. –
El compilador de C# podría tener esa optimización. No lo he comprobado En la mayoría de los casos, estos tipos de concatentaciones se realizan dentro de un bucle for, que no se puede optimizar. El compilador de C# se optimiza para el caso en el que concatena una serie de cadenas const, lo que hace que el compilador emita una sola cadena const y evite por completo la concatenación de tiempo de ejecución. –