Conjunto de matrizes

Dec 15 2022
Hoje em dia, raramente usamos arrays. Na maioria dos casos, usamos List<T>, que fornece mais funcionalidade e é baseado em uma matriz sob o capô.

Hoje em dia, raramente usamos arrays. Na maioria dos casos, usamos List<T>, que fornece mais funcionalidade e é baseado em uma matriz sob o capô. Mas há situações em que o desempenho é a chave ao lidar com muitos objetos.

O que me surpreendeu é que um array simples é duas vezes mais eficiente que uma lista e ainda pode ser otimizado com ArrayPool.

Neste artigo, mostrarei como usar ArrayPool com exemplos de código e desempenho de benchmarking.

Repositório de código

O que é ArrayPool

ArrayPool é um pool de recursos que permite reutilizar instâncias de tipos de array. Você pode usá-lo para alugar e devolver buffers (arrays). Isso melhorará o desempenho quando você criar e destruir matrizes com frequência, que consomem muita memória e COLETOR DE LIXO . Essa classe é thread-safe e você pode usá-la simultaneamente. Ao retornar ao pool, você pode optar por limpar ou não o conteúdo da matriz. A limpeza levará mais tempo, mas sua situação pode exigir a obtenção de uma matriz vazia a cada vez.

Como usá-lo

Existem duas maneiras de acessar arrays da memória do pool.

A primeira e mais simples é usar a propriedade ArrayPool Shared .

ArrayPool<T>.Shared

Você obterá a implementação padrão do pool. Ele contém matrizes de tamanhos diferentes. Ele pode retornar uma matriz maior do que você solicitou, mas certamente não menor. Um pool compartilhado é uma maneira conveniente de reutilizar arrays, mas existem outros melhores.

A maneira mais eficiente é inicializar seu pool usando métodos create.

ArrayPool<T>.Create()

ArrayPool<T>.Create(int maxArrayLength, int maxArraysPerBucket)

Create retorna uma instância personalizada do pool. Você deve armazená-lo em cache para acessá-lo de diferentes locais para reutilizá-lo. O método parametrizado pode ajudar a obter o melhor desempenho. Ele criará uma instância que agrupa arrays de tamanho não superior a maxArrayLength em buckets de tamanho maxArraysPerBucket.

Aproveite o pooling de matrizes em C# para reduzir as alocações e melhorar o desempenho de seus aplicativos.

referência

Este é um teste simples. Vamos comparar as diferenças entre criar um novo array e alugá-lo do pool. Em cada caso, iremos iterar sobre uma coleção de 1_000_000 elementos. Também incluirei List<T> no benchmark para mostrar as vantagens de desempenho dos arrays.

Repositório de código

referência

Conclusões

O que mais me surpreendeu é que um array simples é duas vezes mais eficiente que uma lista em termos de velocidade e uso de memória. E ainda pode ser otimizado com ArrayPool. Usando uma piscina é obviamente o caminho a percorrer.

Há uma diferença de tempo perceptível entre usar uma matriz padrão e uma do pool. A diferença de tempo é o tempo necessário para alocar memória ao criar uma nova matriz a cada vez. Claro, também há uma diferença na alocação de memória. ArrayPool não precisa alocar nova memória. Ele reutiliza o mesmo bloco.

Como aviso, adicionei 'Pool personalizado sem cache' para que você possa ver o que acontece quando cria um novo pool a cada vez. É basicamente a mesma coisa que criar um novo array a cada vez.

Neste exemplo simples, é difícil mostrar a diferença de desempenho entre ArrayPool compartilhado e personalizado. Seria perceptível quando muitos arrays de tamanhos diferentes são usados.

Usar ArrayPool pode nem sempre ser o mais conveniente, mas às vezes pode economizar muito poder de computação quando necessário.