Funções em C# - Benchmark de Concatenação de String C#
- #C#
Introdução
Existem várias maneiras de concatenar strings no C#. Neste artigo vamos mostrar várias formas de fazer isso, usando classes e funções em C#. Será contabilizado o tempo de processamento das concatenações em diversas quantidades de iterações de concatenação para as diferentes formas de concatenar. No final será mostrado o resultado deste processamento.
String Plus
Esta é maneira mais tradicional de concatenar strings, criada desde as primeiras versões do C#. É utilizada em conjunto com o operador '+' como se o resultado fosse uma soma de strings. Exemplo:
string[] name = { "First", "Middle", "Last" };
string str = name[0] + ' ' + name[1] + ' ' + name[2] + '\n';
String Interpolation
Esta forma de concatenar strings usa o operador $ antes da string e coloca as variáveis entre chaves "{}", conforme mostrado abaixo:
string[] name = { "First", "Middle", "Last" };
string str = $"{name[0]} {name[1]} {name[2]}\n";
String Join
Usa o método Join da classe String, onde o primeiro parâmetro é o separador das strings concatenadas que serão passadas nos parâmetros seguintes. Conforme exemplo abaixo:
string[] name = { "First", "Middle", "Last" };
string str = String.Join( ' '
, name[0]
, name[1]
, name[2]
, '\n' );
String Concat
Usa o método Concat da classe String, onde serão concatenados todos os parâmetros passados no método. Conforme exemplo abaixo:
string[] name = { "First", "Middle", "Last" };
string str = String.Concat( name[0]
, ' '
, name[1]
, ' '
, name[2]
, '\n' );
String Format
Usa o método Format da classe String. O resultado é a concatenação das strings passando as variáveis como parâmetro. Dentro da string usamos o índice do parâmetro entre chaves "{}", conforme mostrado abaixo:
string[] name = { "First", "Middle", "Last" };
string str = String.Format("{0} {1} {2}\n", name[0], name[1], name[2]);
String Builder
Usando a classe StringBuilder e os métodos Append para cocatenar e AppendLine para concatenar e ir para nova linha. Diferente das formas vistas anteriormente, a classe StringBuilder otimiza o uso de memória usando alocação dinâmica, apenas incrementando a string final, enquanto as outras formas necessitam criar uma nova string. Exemplo:
string[] name = { "First", "Middle", "Last" };
System.Text.StringBuilder str = new System.Text.StringBuilder();
str.Append(name[0])
.Append(' ')
.Append(name[1])
.Append(' ')
.AppendLine(name[2]);
String List
Esta é uma maneira diferente, usando uma classe List e o método Add para adicionar as strings. Após todas as strings adicionadas é usado o método Join passando o caractere delimitador e a lista como parâmetros, conforme exemplo abaixo:
string[] name = { "First", "Middle", "Last" };
List<String> list = new List<String>();
list.Add(name[0]);
list.Add(name[1]);
list.Add(name[2]);
list.Add("\n");
string str = string.Join(' ', list);
Medindo o Tempo de Processamento na Concatenação
Para medir o tempo de processamento vamos usar o design pattern Strategy para criar várias classes derivadas de uma Interface chamada IConcat, onde cada classe sobrescreve o método Concat para cada tipo específico de concatenação. O método recebe os parâmetros 'int size' que é a quantidade de iterações de concatenação, além de um array de string com três elementos que serão concatenados. O método Concat deve retornar uma tupla com o tempo medido em nanosegundos e o tipo de concatenação realizado. Conforme interface declarada abaixo:
internal interface IConcat
{
(long, string) Concat(int size, string[] name);
}
Para otimizar e garantir processamento em condições igualitárias, sem comprometimento de diferentes configurações de ambiente o que poderia interferir na performance das concatenações, vamos rodar os processos em paralelo. Não vamos entrar em maiores detalhes sobre esta abordagem, pois não faz parte do escopo deste artigo, entretanto o código fonte completo pode ser verificado no repositório https://github.com/G10van1/BenchmarkStringConcat do GitHub.
Comparação das Medições de Tempo de Processamento
O tempo de processamento foi medido para as quantidades de 1, 10, 100, 1000, 10000 e 50000 iterações, nas diversas formas de concatenação conforme mostra a tabela abaixo:
Conclusão
Para quantidades pequenas de concatenações a performance não é muito diferente entre os diversos modelos avaliados, sendo que String Concat, String Plus e StringBuilder foram melhores, já a pior performance foi de String Format. A medida que aumenta o número de concatenações, StringBuilder vai se mostrando melhor e consequentemente a opção mais indicada para concatenação de string.