jeudi 3 juin 2021

Span et ArrayPool

 Span<T> et ArrayPool<T> en C#, deux outils puissants pour écrire du code rapide et optimisé en mémoire, sans sacrifier la sécurité.


🧩 1. Span<T> — Travailler avec la mémoire sans l'allouer

✅ Qu'est-ce que c’est ?

Span<T> est une vue temporaire, rapide et sûre sur un bloc contigu de mémoire, qu’il s’agisse :

  • d’un tableau (T[]),

  • d’une portion de stackalloc,

  • ou d’une mémoire native non managée.

Il vous permet de travailler avec les données sans créer de copie ni allocation sur le heap.

✳️ Exemple simple :

int[] numbers = { 1, 2, 3, 4, 5 };
Span<int> span = numbers.AsSpan(1, 3); // [2, 3, 4]

span[0] = 20;
Console.WriteLine(numbers[1]); // Affiche 20 (modifie le tableau original)

📌 Caractéristiques :

Propriété Valeur
Modifiable ✅ Oui (Span<T>)
Allocation sur le heap ❌ Non
Stockable dans un champ de classe ❌ Non (ref struct)
Accès rapide à la mémoire ✅ Oui

🔒 ReadOnlySpan<T> ?

Même concept, mais lecture seule :

ReadOnlySpan<char> span = "Hello World".AsSpan(6, 5); // "World"

🧩 2. ArrayPool<T> — Réutilisation des tableaux (évite le GC)

✅ Qu’est-ce que c’est ?

ArrayPool<T> permet de réutiliser des tableaux sans les allouer à chaque fois, pour réduire la pression sur le Garbage Collector (GC).

Utile dans les scénarios à haute performance : traitement de fichiers, réseau, sérialisation, etc.


✳️ Exemple simple :

using System.Buffers;

var pool = ArrayPool<byte>.Shared;
byte[] buffer = pool.Rent(1024); // loue un tableau de taille >= 1024

try
{
    // Utilisation du buffer
    buffer[0] = 42;
}
finally
{
    pool.Return(buffer); // Très important : restituer le tableau !
}

📌 Pourquoi c’est utile ?

Avantage Détail
✅ Moins de garbage Réutilise les tableaux
✅ Performance accrue Pas de new byte[] fréquent
✅ Facile à utiliser Juste .Rent() et .Return()

🧠 Quand utiliser quoi ?

Besoin Utiliser
Travailler sur une portion de mémoire sans allouer Span<T>
Réutiliser des buffers entre plusieurs appels ArrayPool<T>
Parser rapidement du texte ou des données binaires Span<T>, ReadOnlySpan<T>
Code hautement performant ou temps réel Les deux combinés ✅

🔄 Exemple combiné : ArrayPool<T> + Span<T>

var buffer = ArrayPool<byte>.Shared.Rent(1000);
try
{
    Span<byte> span = buffer.AsSpan(0, 500);
    span.Clear(); // Efface les 500 premiers octets
}
finally
{
    ArrayPool<byte>.Shared.Return(buffer);
}


Aucun commentaire:

Enregistrer un commentaire