Concatenação de strings super lenta

3 respostas
C

Hoje eu resolvi testar o tempo que leva para concatenar strings 1 milhão de vezes e me apavorei.

Enquanto o primeiro código levou apenas 25 milisegundos para executar, o outro eu deixei rodando por mais de 10 minutos e não terminou! Absurdo!

StringBuilder builder = new StringBuilder(); for (int i = 0; i < 1000000; i++) { builder.append("0"); }

String s = ""; for (int i = 0; i < 1000000; i++) { s = s + "0"; }

3 Respostas

C

Eu já imaginava que seria lento, mas não tão lento assim! :shock:

E

É isso mesmo. Evite concatenar strings, use sempre StringBuilder.

Antes de alguém sair jogando pedras no Java, experimente rodar o mesmo programa em C# (.NET). Você vai ver que o comportamento é muito semelhante (usar System.Text.StringBuilder.Append é MUITO mais rápido que += . )

Isso é porque o seu programa que usa “+=” é convertido, pelo compilador, para algo como:

String s = "";
for (int i = 0; i < 1000000; ++i) {
    s = (new StringBuilder (s).append ("0")).toString();
}

Ou seja, a cada “+=”, é criado um NOVO objeto StringBuilder (com uma cópia física dos caracteres da string original), e um NOVO objeto String (com uma cópia física dos caracteres da StringBuilder na hora em que foi chamado o método toString(), sem contar os 2 NOVOS objetos char[] que contém os tais caracteres e que são atributos dessas classes StringBuilder e String. Total de objetos criados e reciclados : 4, sendo que 2 desses objetos (char[]) são muito grandes no seu exemplo. Isso força muito o Garbage Collector, e é por isso que leva vários minutos para concatenar 1 milhão de strings grandes (mais de 500.000 caracteres, ou seja, 1.000.000 bytes).

Em contrapartida, seu primeiro programa só cria objetos novos (char[]) muito de vez em quando, quando o buffer interno do StringBuilder estoura e ele é obrigado a realocar o tal buffer.

furutani

Ótimo exemplo de otimização de código.

Criado 21 de abril de 2010
Ultima resposta 21 de abr. de 2010
Respostas 3
Participantes 3