Desenvolvimento - C#
Por que utilizar StringBuilder?
Este artigo aborda o conceito de imutabilidade presente em tipos String, e faz um paralelo entre o modelo convencial para concatenação de string com a classe StringBuilder do .NET Framework. Neste artigo podemos perceber resultados positivos e ganhos de performance/uso de memória ao empregarmos melhores práticas em concatenações de textos.
por Luiz Gustavo Jordão SoaresÉ bastante comum em nosso dia a dia nos depararmos com certas práticas de desenvolvimento que utilizamos, mas nunca nos perguntamos: "Por quê utilizo dessa forma?" Ou seja, um uso inconsciente que por uma questão de hábito, ou mesmo descuido, continua em nossas rotinas de trabalho e se perpetua por anos e anos de utilização, independente da linguagem de programação.
Iremos abordar neste artigo algo bem simples no mundo da programação, que é o uso da "concatenção".
Concatenação como todos nós sabemos, é quando queremos unir dois (2) ou mais valores do tipo string no intuito de se criar um novo valor. Por exemplo:
string myString = "Hello" + " world!";
O que nós esquecemos muitas vezes é o conceito que há por trás disso. Quando trabalhamos com strings, devemos nos lembrar do conceito da imutabilidade, ou seja, as strings são imutáveis (isso mesmo! o conteúdo não se altera nunca).
Quando fazemos uma concatenação entre duas strings e atribuímos a uma outra string (conforme o exemplo), estaremos na verdade alocando um novo espaço em memória para ser atribuído à myString, e o valor antigo é desprezado e perdido em memória.
Pode parecer algo completamente imperceptível, mas imagine quando estamos em um cenário em que precisamos realizar concatenações de strings dentro de um loop? Agora imagine que neste loop realizamos milhares e milhares de repetições? Estaremos nesse caso, criando e desprezando milhares e milhares de strings em memória, e estaremos dessa forma afetando diretamente os recursos de processamento e memória da máquina onde o programa está sendo utilizado.
Para termos uma idéia de como este descuido pode afetar a qualidade e performance de nossos aplicativos, será criado logo abaixo, um programa que utiliza concatenações dentro de um loop, e este loop terá uma quantidade de repetições elevada, de forma que possamos visualizar melhor o resultado dos testes, este também será cronometrado para termos uma idéia do tempo consumido.
static void Main(string[] args)
{
string myString = "Start counting: ";
DateTime initialTime = DateTime.Now;
for (int i = 0; i <= 100000; i++)
{
myString += i.ToString();
}
DateTime finalTime = DateTime.Now;
TimeSpan time = finalTime - initialTime;
Console.Write("The elapsed time was: {0} ", time.TotalSeconds);
Console.Read();
}
Analisemos agora o resultado do programa acima:
Como podemos perceber, o programa demora cerca de quarenta (40) segundos até o final de sua execução, pois muito tempo foi perdido durante o loop.
Para evitarmos o
consumo de recursos de máquina e realizarmos concatenações de maneira menos
dispendiosa, o .NET Framework possui uma classe chamada StringBuilder
("Construtor de String"), onde podemos facilmente utilizá-la em
cenários que exigem muitas concatenações.
A classe StringBuilder está localizada no namespace "System.Text"
e pode ser implementada (usando o mesmo programa) da seguinte forma:
static void Main(string[] args)
{
//Instância da classe StringBuilder
StringBuilder sBuilder = new StringBuilder();
//Adicionamos itens através do método "Append"
sBuilder.Append("Start counting: ");
DateTime initialTime = DateTime.Now;
for (int i = 0; i <= 100000; i++)
{
sBuilder.Append(i.ToString());
}
DateTime finalTime = DateTime.Now;
TimeSpan time = finalTime - initialTime;
Console.Write("The elapsed time was: {0} ", time.TotalSeconds);
Console.Read();
}
Analisemos agora o resultado do novo programa:
Com a utilização da classe StringBuilder, podemos perceber a grande diferença em relação ao modelo de concatenação tradicional.
Veja abaixo a tabela comparativa entre os dois programas:
Comparativo entre modelos de concatenação |
||
Modelo |
Quantidade de loops |
Tempo de processamento |
Tradicional |
100.000 |
~40 segundos |
Classe StringBuilder |
100.000 |
~0,1 segundos |
Espero que tenham gostado deste artigo. Até a próxima!