¿C # optimiza la concatenación de cadenas literales?

Por ejemplo, el comstackdor sabe traducir

string s = "test " + "this " + "function"; 

a

 string s = "test this function"; 

y así evitar el golpe de rendimiento con la concatenación de cadenas?

Sí. Esto está garantizado por la especificación C #. Está en la sección 7.18 (de la especificación C # 3.0):

Siempre que una expresión cumpla con los requisitos enumerados anteriormente, la expresión se evalúa en tiempo de comstackción. Esto es cierto incluso si la expresión es una sub-expresión de una expresión más grande que contiene construcciones no constantes.

(Los “requisitos enumerados anteriormente” incluyen el operador + aplicado a dos expresiones constantes).

Ver también esta pregunta .

Solo una nota al margen sobre un tema relacionado: el comstackdor de C # también ‘optimiza’ múltiples concatenaciones que involucran non-literales usando el operador ‘ + ‘ a una sola llamada a una sobrecarga de múltiples parámetros del método String.Concat ().

Asi que

 string result = x + y + z; 

comstack a algo equivalente a

 string result = String.Concat( x, y, z); 

en lugar de la posibilidad más ingenua:

 string result = String.Concat( String.Concat( x, y), z); 

Nada impactante, pero solo quería agregar este bit a la discusión sobre la optimización de concatenación literal de cadenas. No sé si este comportamiento es obligatorio según el estándar del idioma o no.

Sí.

C # no solo optimiza la concatenación de literales de cadena, sino que también contrae literales de cadena equivalentes en constantes y utiliza punteros para hacer referencia a todas las referencias a la misma constante.

Sí, puede ver esto explícitamente usando ILDASM.

Ejemplo:

Aquí hay un progtwig que es similar a su ejemplo seguido del código CIL comstackdo:

Nota: Estoy usando la función String.Concat () solo para ver cómo trata el comstackdor los dos métodos diferentes de concatenación.

Progtwig

 class Program { static void Main(string[] args) { string s = "test " + "this " + "function"; string ss = String.Concat("test", "this", "function"); } } 

ILDASM

 .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 29 (0x1d) .maxstack 3 .locals init (string V_0, string V_1) IL_0000: nop IL_0001: ldstr "test this function" IL_0006: stloc.0 IL_0007: ldstr "test" IL_000c: ldstr "this" IL_0011: ldstr "function" IL_0016: call string [mscorlib]System.String::Concat(string, string, string) IL_001b: stloc.1 IL_001c: ret } // end of method Program::Main 

Observe cómo en IL_0001 el comstackdor creó la constante “probar esta función” en lugar de cómo el comstackdor trata la función String.Concat (), que crea una constante para cada uno de los parámetros .Concat (), y luego llama al .Concat () función.

De la boca de los caballos:

La concatenación es el proceso de agregar una cadena al final de otra cadena. Cuando concatena literales de cadena o constantes de cadena utilizando el operador +, el comstackdor crea una sola cadena. No se produce la concatenación de tiempo de ejecución. Sin embargo, las variables de cadena se pueden concatenar solo en tiempo de ejecución. En este caso, debe comprender las implicaciones de rendimiento de los diversos enfoques.

http://msdn.microsoft.com/en-us/library/ms228504.aspx

Creo que la respuesta es sí, pero tendrías que ver lo que dice el comstackdor … simplemente comstack y usa reflector en él 🙂

Tenía una pregunta similar, pero sobre VB.NET en lugar de C #. La forma más sencilla de verificar esto fue ver el ensamblado comstackdo en Reflector.

La respuesta fue que tanto el comstackdor C # como el comstackdor VB.NET optimizan la concatenación de literales de cadena.