A classe System.String representa textos como uma coleção de caracteres Unicode. Um objeto String é então uma coleção sequencial de objetos do tipo System.Char que representam a string.
Uma característica que alguns não conhecem é que a string é imutável, ou seja, o seu valor não pode ser modificado (read-only). Verifique que a maioria dos métodos existentes na classe System.String retornam uma nova string e não modificam a instância da mesma.
Quando concatenamos a string com uma outra string, por exemplo...
string str1 = "a"; str1 = str1 + "b";
uma nova instância da classe string é criada e atribuída a variável str1. Isso faz com que códigos que concatenam strings extensivamente utilizem muita memória e consequentemente tenham uma perda de performance.
A classe System.Text.StringBuilder representa então uma string mutável de caracteres e representa um ganho de performance enorme se utilizada em nosso código.
Vou demonstrar abaixo dois códigos que podem ser utilizados em uma aplicação Console e que irão demonstrar a diferença de performance quando utilizamos StringBuilder. Para realizar a medição do tempo utilizaremos a classe System.Diagnostics.Stopwatch.
Digamos então que temos o seguinte código:
using System; using System.Text; using System.Diagnostics; namespace CSharpStringBuilderPerformance { // Main program class Program { static void Main(string[] args) { string suaString = ""; // cria StopWatch Stopwatch stopWatch = new Stopwatch(); // inicia medição do tempo stopWatch.Start(); // loop para teste for (int i = 0; i < 10000; ++i) suaString += "Número: " + i.ToString() + "\n"; // finaliza medição do tempo stopWatch.Stop(); // tempo decorrido Console.WriteLine(stopWatch.ElapsedMilliseconds); } } }
O que o código faz é bem simples, somente cria uma variável chamada suaString e com um loop de 0 a 9999 realiza concatenação da string "Número: (contador)" seguido de uma nova linha.
Os métodos Start e Stop do objeto da classe Stopwatch realizam respectivamente o início da medida do tempo e o final da medida do tempo.
Realizando o processamento do código acima 10 vezes tive os seguintes resultados computados em milisegundos:
1728
1708
1720
1712
1709
1726
1717
1700
1731
1702
Obs: Dependendo do seu hardware você pode ter valores diferentes (óbvio).
Ok, agora vamos utilizar a classe StringBuilder e o método AppendLine da mesma para concatenar a string. Vou somente colocar o código do método Main para simplificar melhor o exemplo.
static void Main(string[] args) { // cria StringBuilder StringBuilder stringBuilder = new StringBuilder(); // cria StopWatch Stopwatch stopWatch = new Stopwatch(); // inicia medição do tempo stopWatch.Start(); // loop para teste for (int i = 0; i < 10000; ++i) stringBuilder.AppendLine("Número: " + i.ToString()); // finaliza medição do tempo stopWatch.Stop(); // tempo decorrido Console.WriteLine(stopWatch.ElapsedMilliseconds); }
A idéia é substituir o objeto string por um objeto StringBuilder e utilizar o método AppendLine. Se existir a necessidade de transformar o StringBuilder em String novamente é só utilizarmos o método ToString().
Processando o código com StringBuilder 10 vezes temos o incrível resultado abaixo:
6
5
7
6
5
8
9
10
9
6
Perceberam a diferença de performance? Portanto utilizem o StringBuilder sempre que possível.
Alguns links de ajuda:
String Class
http://bit.ly/6ebptP
StringBuilder Class
http://bit.ly/64pDlE
Stopwatch Class
http://bit.ly/8TcpCG
Hi, thanks for your explication, helped me much...
ResponderExcluir