C # otimiza a concatenação de literais de string?

Por exemplo, o compilador sabe traduzir

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

para

 string s = "test this function"; 

e assim evitar o impacto no desempenho com a concatenação de string?

Sim. Isso é garantido pela especificação C #. Está na seção 7.18 (da especificação C # 3.0):

Sempre que uma expressão atende aos requisitos listados acima, a expressão é avaliada em tempo de compilation. Isso é verdadeiro mesmo se a expressão for uma subexpressão de uma expressão maior que contém construções não constantes.

(Os “requisitos listados acima” incluem o operador + aplicado a duas expressões constantes.)

Veja também esta questão .

Apenas uma nota lateral sobre um assunto relacionado – o compilador C # também ‘otimizará’ múltiplas concatenações envolvendo não-literais usando o operador ‘ + ‘ para uma única chamada para uma sobrecarga multiparâmetro do método String.Concat ().

assim

 string result = x + y + z; 

compila para algo equivalente a

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

em vez da possibilidade mais ingênua:

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

Nada de arrepiante, mas só queria adicionar esse bit à discussão sobre a otimização de concatenação literal de string. Eu não sei se esse comportamento é obrigatório pelo padrão de linguagem ou não.

Sim.

O C # não apenas otimiza a concatenação de literais de string, como também retém literais de string equivalentes em constantes e usa pointers para referenciar todas as referências à mesma constante.

Sim – Você pode ver isso explicitamente usando o ILDASM.

Exemplo:

Aqui está um programa que é semelhante ao seu exemplo seguido pelo código CIL compilado:

Nota: Estou usando a function String.Concat () apenas para ver como o compilador trata os dois methods diferentes de concatenação.

Programa

 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 como no IL_0001 o compilador criou a constante “test this function” ao contrário de como o compilador trata a function String.Concat () – que cria uma constante para cada um dos parâmetros .Concat (), então chama o .Concat () function.

Da boca dos cavalos:

Concatenação é o processo de append uma string ao final de outra string. Quando você concatena literais de string ou constantes de string usando o operador +, o compilador cria uma única string. Nenhuma concatenação de tempo de execução ocorre. No entanto, variables ​​de seqüência de caracteres podem ser concatenadas somente em tempo de execução. Nesse caso, você deve entender as implicações de desempenho das várias abordagens.

http://msdn.microsoft.com/pt-br/library/ms228504.aspx

Eu acredito que a resposta para isso é sim, mas você teria que olhar para o que o compilador cospe … apenas compile, e use o refletor nele 🙂

Eu tive uma pergunta semelhante, mas sobre VB.NET em vez de C #. A maneira mais simples de verificar isso foi ver o assembly compilado em Reflector.

A resposta foi que tanto o compilador C # quanto o VB.NET otimizam a concatenação de literais de string.