Pergunta

A seqüência de imutabilidade trabalho de declaração, ou por cordas dentro de uma declaração?

Por exemplo, eu entendo que o seguinte código irá alocar duas cordas na pilha.

string s = "hello ";
s += "world!";

"Olá" permanecerá no heap até lixo coletado; e é agora referências "Olá mundo!" na pilha. No entanto, quantas cordas tem a seguinte linha de alocar na pilha ... 1 ou 2? Além disso, existe uma ferramenta / maneira de verificar os resultados?

string s = "goodbye " + "cruel world!";
Foi útil?

Solução

O compilador tem um tratamento especial para concatenação, razão pela qual o segundo exemplo é sempre apenas um string. E "internar" significa que mesmo se você executar esta linha 20000 vezes ainda há apenas 1 string.

Re testar os resultados ... a maneira mais fácil (neste caso) é provavelmente a olhar no reflector:

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] string s)
    L_0000: ldstr "goodbye cruel world!"
    L_0005: stloc.0 
    L_0006: ldloc.0 
    L_0007: call void [mscorlib]System.Console::WriteLine(string)
    L_000c: ret 
}

Como você pode ver (ldstr), o compilador fez isso para você já.

Outras dicas

Strings literais são internados Isto significa que "hello " não residem na pilha, mas no segmento de dados [ver comentário] do progama (e não é, portanto, elegível para coleta de lixo), mesmo vale para "world", como por "hello world" que podem também ser internado, se o compilador é suficientemente inteligente.

"goodbye cruel world" irá ser internado desde concatenação literal é tratado algo pelo compilador.


Editar: Não tenho certeza sobre a declaração segmento de dados, consulte este questão para mais informações.

Na verdade, provavelmente 3. uma string const para "adeus", uma string const para "mundo cruel", e, em seguida, uma nova seqüência para o resultado.

Você pode descobrir com certeza, olhando para o código gerado. Depende do compilador, (e, de fato, na linguagem, isso não é óbvio), mas você pode ler a saída do g ++ usando o sinalizador -a (eu acho, verifique a página de manual) para obter o código intermediário .

não confiam no que você "sabe" sobre strings. Você pode olhar através do código-fonte para a implementação de string. Por exemplo o seu exemplo:

string s = "goodbye " + "cruel world!";

Em java iria alocar uma única cadeia. Java desempenha alguns truques muito bonito e seria difícil de ser mais esperto - apenas nunca otimizar até que você precisa

Actualmente, contudo, tanto quanto eu sei, usando o seguinte:

String s="";
for(int i=0;i<1000;i++)
    s+=" ";

Para criar uma cadeia mil espaço ainda tende a ser extremamente ineficiente

Anexar em um loop é muito ruim, mas por outro lado é provavelmente tão eficiente quanto StringBuilder.

Tenha cuidado aqui, porque o compilador pode fazer algumas otimizações muito diferentes quando os valores de cadeia são conhecidos em tempo de compilação. Se as cordas que você está usando não são conhecidos até a execução (retirado de um arquivo de configuração, banco de dados ou entrada do usuário), você vai ver alguns IL muito diferente.

Se você está indo só para fazer uma ou duas concatenações eu não se preocupar com isso.

No entanto, se você tem muitos concatenações, ou você tem um loop, então você definitivamente querer tomar precauções. No mundo Java que significa que você usa insteads StringBuffer de concatenação de string.

Se não é apenas em uma linha, a concatenação de duas cordas pode ser conseguido por fazer a primeira corda em um StringBuffer, fazendo a concatenação, e retornando a string de resultado.

Criando o StringBuffer si mesmo pode parecer um exagero, mas isso é o que vai acontecer de qualquer maneira .-

Por todos os meios não prematuramente otimizar, mas não desconto como mal concatonations cordas de elevada performance pode ser. Não é a criação do objeto, mas o trabalho GC que ela provoca.

Há um laboratório em (engenheiro de escalonamento ASP.NET) blogue Tess de Ferrnandez que o show um exemplo (, concedido um pouco exagerado) de como corda concatonation pode trazer um servidor de joelhos .

Se o compilador é "inteligente", ela só vai ser uma string com "Adeus mundo cruel!"

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top