Gruppo di matrici

Dec 15 2022
Al giorno d'oggi, raramente usiamo gli array. Nella maggior parte dei casi, utilizziamo List<T>, che fornisce più funzionalità e si basa su un array sotto il cofano.

Al giorno d'oggi, raramente usiamo gli array. Nella maggior parte dei casi, utilizziamo List<T>, che fornisce più funzionalità e si basa su un array sotto il cofano. Ma ci sono situazioni in cui le prestazioni sono la chiave quando si ha a che fare con molti oggetti.

Ciò che mi ha sorpreso è che un semplice array è due volte più efficiente di un elenco e può ancora essere ottimizzato con ArrayPool.

In questo articolo, ti mostrerò come utilizzare ArrayPool con esempi di codice e prestazioni di benchmarking.

Deposito di codice

Che cos'è ArrayPool

ArrayPool è un pool di risorse che consente di riutilizzare istanze di tipi di matrice. Puoi usarlo per affittare e restituire buffer (array). Migliorerà le prestazioni quando crei e distruggi frequentemente array, che sono pesanti sulla memoria e GARBAGE COLLECTOR . Questa classe è thread-safe e puoi usarla contemporaneamente. Tornando al pool, puoi scegliere di cancellare o meno il contenuto dell'array. La cancellazione richiederà più tempo, ma la tua situazione potrebbe richiedere di ottenere ogni volta un array vuoto.

Come usarlo

Esistono due modi per accedere agli array dalla memoria del pool.

Il primo e più semplice consiste nell'usare la proprietà ArrayPool Shared .

ArrayPool<T>.Condiviso

Otterrai l'implementazione predefinita del pool. Contiene array di diverse dimensioni. Può restituire un array più grande di quello che hai richiesto ma certamente non più piccolo. Un pool condiviso è un modo conveniente per riutilizzare gli array, ma ce ne sono di migliori.

Il modo più efficiente consiste nell'inizializzare il pool utilizzando i metodi di creazione.

ArrayPool<T>.Create()

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

Il metodo Create restituisce un'istanza personalizzata del pool. È necessario memorizzarlo nella cache per accedervi da posizioni diverse per riutilizzarlo. Il metodo parametrizzato può aiutare a ottenere le migliori prestazioni. Creerà un'istanza che raggruppa array di lunghezza non superiore a maxArrayLength in bucket di dimensione maxArraysPerBucket.

Sfrutta il pool di array in C# per ridurre le allocazioni e migliorare le prestazioni delle tue applicazioni.

Segno di riferimento

Questo è un test semplice. Confronteremo le differenze tra la creazione di un nuovo array e il noleggio dal pool. In ogni caso, itereremo su una raccolta di 1_000_000 elementi. Includerò anche List<T> nel benchmark per mostrare i vantaggi in termini di prestazioni degli array.

Deposito di codice

prova delle prestazioni

Conclusioni

Ciò che mi ha sorpreso di più è che un array semplice è due volte più efficiente di un elenco in termini di velocità e utilizzo della memoria. E può ancora essere ottimizzato con ArrayPool. Usare una piscina è ovviamente la strada da percorrere.

C'è una notevole differenza di tempo tra l'utilizzo di un array standard e uno dal pool. La differenza di orario è il tempo necessario per allocare la memoria quando si crea ogni volta un nuovo array. Naturalmente, c'è anche una differenza nell'allocazione della memoria. ArrayPool non ha bisogno di allocare nuova memoria. Riutilizza lo stesso blocco.

Come avvertimento, ho aggiunto "Pool personalizzato senza memorizzazione nella cache" in modo che tu possa vedere cosa succede quando crei un nuovo pool ogni volta. È fondamentalmente la stessa cosa che creare ogni volta un nuovo array.

In questo semplice esempio, è difficile mostrare la differenza di prestazioni tra ArrayPool condiviso e personalizzato. Sarebbe evidente quando vengono utilizzati molti array di dimensioni diverse.

L'utilizzo di ArrayPool potrebbe non essere sempre il più conveniente, ma a volte può farti risparmiare molta potenza di calcolo quando necessario.