C#

31 jul, 2023

Quais são as diferenças entre um Array e uma Lista no C# ?

Publicidade

Tanto um Array quanto uma List servem como coleções de valores, mas diferem em como armazenam seu conteúdo na memória e como podem ser acessados. Para usar qualquer um de forma eficaz, você precisará entender as diferenças entre eles para que possa escolher o caminho certo para seus propósitos.

O que é um Array ?

Um Array é uma estrutura que representa uma coleção ordenada de valores ou objetos de tamanho fixo com o mesmo tipo. As arrays facilitam a organização e a operação em grandes quantidades de dados. Por exemplo, em vez de criar 100 variáveis inteiras, você pode simplesmente criar um array que armazena todos esses números inteiros.

Exemplos:

string[] carros = {“Volvo”, “Ford”, “Mazda”};

int[] numeros = {10, 20, 30, 40};

Uma das principais características de um array é que eles sempre têm um comprimento definido, que é igual ao número de elementos que cabem no seu interior.

O que é uma List ?

Uma lista é uma coleção de objetos fortemente tipados que podem ser acessados por índice e com métodos para classificar, pesquisar e modificar a lista. Uma lista pode ter um grupo de objetos com tipos diferentes.

Exemplos:

var carros = new List<string>();
carros.Add("Volvo");
carros.Add("Ford");
carros.Add("Mazda");

A principal característica de um List (diferença com um Array) é que seu comprimento não precisa ser definido, eles podem ter um comprimento variável.

Usando a Memória

A seguir veremos como os arrays e as listas usam a memória.

De forma bem resumida a memória é o espaço em que o aplicativo “lembra” informações ou dados que são usados durante um período de tempo. É como a memória humana, que retém as coisas.

Quando falamos em uso de memória, muitas vezes é confundido com o tamanho da memória que ele usa no disco e é aí que surgem as dúvidas.

Vamos rever rapidamente os 2 tipos de memória que existem:

Memória estática: O tipo de memória que é definido em tempo de compilação. Esse espaço de memória é reservado para uma variável e não pode ser alterado em tempo de execução.

Memória dinâmica: O tipo de memória usado em tempo de execução. Este espaço de memória também é reservado para uma variável, mas neste caso pode ser modificado em tempo de execução.

Para esta comparação entre Array e List, vamos focar no que nos interessa agora: Memória dinâmica.

Memória Dinâmica – Arrays

Suponha que temos espaço na memória dinâmica, vamos pensar em células e cada célula armazena um valor e agora, imagine que já temos várias células ocupadas por alguma coisa.  Vamos ilustrar isso com a figura baixo:

Agora, vamos imaginar que queremos adicionar à memória nosso Array anterior, aquele com os carros :

string[] carros = {“Volvo”, “Ford”, “Mazda”};

O resultado seria algo assim:  

Array :    

  • [0] Volvo
  • [1] Ford
  • [2] Mazda

Tudo bem, e se eu quiser adicionar outro elemento ao Array?

Por exemplo BMW.

Se a princípio você acha que ele iria para a próxima célula (após o primeiro X, abaixo de Volvo), você falhou.

Esta é a principal característica do Array, ele deve ser sempre contínuo na memória. Ou seja, todos os elementos do Array devem estar próximos uns dos outros, não podem ser separados.

Então, se adicionarmos BMW, o resultado seria o seguinte:

Assim, um Array sempre procurará o número necessário de células livres próximas umas das outras para colocar seus valores lá.

A memória do array é estática e contínua.

Os arrays são contínuos na memória, o que torna exaustivo (no sentido de desempenho) inserir partes no meio da lista. A vantagem é a capacidade de realizar acesso aleatório.

Agora que já vimos como um Array funciona na memória, vamos ver como um List funciona na memória.

Memória Dinâmica – List

As listas funcionam com nós, um nó consiste em um valor e um ponteiro para o próximo nó.

Existem também ponteiros de início e fim, o que significa que se eu quiser o valor Mazda (tomando o exemplo os carros), eu simplesmente seguiria os ponteiros até chegar nele:

Agora vamos imaginar que queremos adicionar o BMW.

Bem, simplesmente o ponteiro do último elemento (que é Mazda) apontará para um novo elemento (que será BMW) e o ponteiro deste último, apontará para o ponteiro final.

 

Dessa forma uma lista pode continuar na próxima célula livre, e, os elementos de uma lista não precisam estar todos juntos em uma linha.

A memória de lista é dinâmica e aleatória.

As listas são partes que se desdobram na memória, ligam-se. Isso permite a inserção direta na lista; no entanto, o acesso aleatório sem outras estruturas de dados não é viável.

Agora, você conhece as diferenças entre um Array e um List em termos de memória, mas e o desempenho?

Acho que você já tem uma ideia, mas vamos um pouco mais fundo.

Desempenho : Array x List

Vamos aplicar um teste prático para medir o desempenho.

Teremos uma classe que carregará um conjunto de registros dentro de um loop.

Os testes que faremos serão os mesmos para listas e arrays onde usaremos os tipos:  <int>, <object>, <long> e <ulong>

O código usado será o seguinte :

using System.Diagnostics;ListArrayTeste listArrayTeste = new ListArrayTeste();
Stopwatch stopWatch = new Stopwatch();
int iteracoes = 10000;

//List int
stopWatch.Start();
listArrayTeste.ListInt(iteracoes);
stopWatch.Stop();
Console.WriteLine(“List<int> => ” + stopWatch.ElapsedTicks);
stopWatch.Reset();

//List object
stopWatch.Start();
listArrayTeste.ListObject(iteracoes);
stopWatch.Stop();
Console.WriteLine(“List<object> => ” + stopWatch.ElapsedTicks);
stopWatch.Reset();

//List long
stopWatch.Start();
listArrayTeste.ListLong(iteracoes);
stopWatch.Stop();
Console.WriteLine(“List<long> => ” + stopWatch.ElapsedTicks);
stopWatch.Reset();

//List ulong
stopWatch.Start();
listArrayTeste.ListUlong((ulong)iteracoes);
stopWatch.Stop();
Console.WriteLine(“List<ulong> => ” + stopWatch.ElapsedTicks);
stopWatch.Reset();

//Array int
stopWatch.Start();
listArrayTeste.ArrayInt(iteracoes);
stopWatch.Stop();
Console.WriteLine(“Array<int> => ” + stopWatch.ElapsedTicks);
stopWatch.Reset();

//Array object
stopWatch.Start();
listArrayTeste.ArrayObject(iteracoes);
stopWatch.Stop();
Console.WriteLine(“Array<object> => ” + stopWatch.ElapsedTicks);
stopWatch.Reset();

//Array long
stopWatch.Start();
listArrayTeste.ArrayLong(iteracoes);
stopWatch.Stop();
Console.WriteLine(“Array<long> => ” + stopWatch.ElapsedTicks);
stopWatch.Reset();

//Array ulong
stopWatch.Start();
listArrayTeste.ArrayUlong((ulong)iteracoes);
stopWatch.Stop();
Console.WriteLine(“Array<ulong> => ” + stopWatch.ElapsedTicks);
stopWatch.Reset();

Console.ReadKey();

public class ListArrayTeste
{
//List int
public void ListInt(int iteracoes)
{
List<int> li = new List<int>();

        for (int i = 0; i < iteracoes; i++)
{
li.Add(i);
}
}

    //List object
public void ListObject(int iteracoes)
{
List<object> li = new List<object>();

        for (int i = 0; i < iteracoes; i++)
{
li.Add(i);
}
}

    //List long
public void ListLong(long iteracoes)
{
List<long> li = new List<long>();

        for (int i = 0; i < iteracoes; i++)
{
li.Add(i);
}
}

    //List ulong
public void ListUlong(ulong iteracoes)
{
List<ulong> li = new List<ulong>();

        for (ulong i = 0; i < iteracoes; i++)
{
li.Add(i);
}
}

    //Array int
public void ArrayInt(int iteracoes)
{
int[] a = new int[iteracoes];

        for (int i = 0; i < iteracoes; i++)
{
a[i] = i;
}
}

    //Array object
public void ArrayObject(int iteracoes)
{
object[] a = new object[iteracoes];

        for (int i = 0; i < iteracoes; i++)
{
a[i] = i;
}
}

    //Array long
public void ArrayLong(long iteracoes)
{
long[] a = new long[iteracoes];

        for (long i = 0; i < iteracoes; i++)
{
a[i] = i;
}
}

    //Array ulong
public void ArrayUlong(ulong iteracoes)
{
ulong[] a = new ulong[iteracoes];

        for (ulong i = 0; i < iteracoes; i++)
{
a[i] = i;
}
}
}

O resultado obtido é o seguinte:

O resultado pode depender de diversos fatores envolvidos mas já podemos tirar nossas conclusões montando uma tabela de resultados:

Tipo List Array Diferença
int 3123 1316 1807 (57%)
object 3454 2307 1147 (33%)
long 6321 975 5346 (84%)
ulong 2115 1062 1053 (49%)

Os números não mentem, e ,como podemos ver os Arrays podem ser até 84 % mais rápidos que as Listas.

Naturalmente dependendo do tipo de operação que você vai precisar realizar usar a classe List pode ser muito mais indicado, mas considerando apenas o desempenho , os Arrays são mais rápidos.

*O conteúdo deste artigo é de responsabilidade do(a) autor(a) e não reflete necessariamente a opinião do iMasters.