C# - Inicializando listas para aumentar o desempenho
Nesta dica veremos como aumentar o desempenho inicializando listas do tipo List<T>. |
Uma List<T> é uma classe genérica na linguagem C# que representa uma lista dinâmica de elementos do tipo T. Essa classe é parte do namespace System.Collections.Generic e fornece uma estrutura de dados flexível para armazenar e manipular itens.
Algumas
coleções, como List<T>, têm um tamanho inicial predefinido e
sempre que você adiciona um novo item à coleção, há dois
cenários:
1- A coleção tem espaço livre, alocado,
mas ainda não preenchido, portanto, adicionar um item é
imediato;
2- A coleção já está cheia: internamente, o .NET redimensiona a
coleção, para que na próxima vez que você adicionar um novo
item, voltemos à opção nº 1.
Claramente, a segunda abordagem tem um impacto no desempenho
geral. Podemos provar isso ?
Sim, podemos testar o desempenho da alocação de memória e realocação em tempo de execução da coleção List<T> no C#.
Podemos fazer isso criando um loop que adiciona um grande número de elementos a uma lista vazia. Podemos então comparar o tempo de execução de duas listas: uma com um tamanho inicial definido e outra sem um tamanho inicial definido.
Por exemplo, o código a seguir cria duas listas: uma com um tamanho inicial definido de 100000 elementos e outra sem um tamanho inicial definido. O código então adiciona 1000000 elementos a cada lista e mede o tempo necessário para concluir a operação:
Nota: Este código foi criado no VS 2022 usando o recurso Top Level Statement
using
System.Diagnostics; const int NUM_ITENS = 1000000;const int INITIAL_CAPACITY = 100000;var stopwatch = new Stopwatch();stopwatch.Start(); // Lista com tamanho inicial definido var lista1 = new List<int>(INITIAL_CAPACITY);for (int i = 0; i < NUM_ITENS; i++){ lista1.Add(i); } stopwatch.Stop(); Console.WriteLine( $"Tempo para adicionar {NUM_ITENS} itens a uma listacom tamanho inicial de {INITIAL_CAPACITY}: {stopwatch.ElapsedMilliseconds} ms"); stopwatch.Reset(); / / Lista sem tamanho inicial definidovar lista2 = new List<int>();for (int i = 0; i < NUM_ITENS; i++){ lista2.Add(i); } stopwatch.Stop(); Console.WriteLine( $"Tempo para adicionar {NUM_ITENS} itens a umalista sem tamanho inicial definido: {stopwatch.ElapsedMilliseconds} ms"); Console.ReadKey(); |
Executando o projeto iremos obter o seguinte resultado:
.
Os resultados mostram que a lista com um tamanho inicial definido tem um desempenho melhor do que a lista sem um tamanho inicial definido. Isso ocorre porque a lista com tamanho inicial definido não precisa realocar a memória para acomodar novos itens, enquanto a lista sem tamanho inicial definido precisa realocar a memória quando a capacidade atual é excedida.
Dessa forma, para obter o melhor desempenho ao usar a coleção List<T>, recomenda-se seguir as seguintes práticas:
No entanto, é importante notar que o desempenho pode variar dependendo do tamanho inicial da lista e do número de elementos adicionados. Em geral, é recomendável definir um tamanho inicial para a lista sempre que possível para melhorar o desempenho em cenários de grande volume de dados.
E estamos conversados ...
"Portanto, nada julgueis antes de tempo, até que o Senhor venha, o qual
também trará à luz as coisas ocultas das trevas, e manifestará os desígnios dos
corações; e então cada um receberá de Deus o louvor."
1 Coríntios 4:5
Referências:
LINQ - Gerando um Produto Cartesiano - Macoratti
C# - Salvando e Lendo informações em um arquivo XML - Macoratti