Con l'introduzione di .NET Core, Microsoft ha messo in discussione l'intero .NET Framework che si è sviluppato negli anni e, grazie ad un nuovo processo di sviluppo, fatto da iterazioni più veloci, il coinvolgimento della community e il confrontarsi con altri prodotti, questo ha portato ad un'estrema ottimizzazione delle architetture e le prestazioni del runtime e delle librerie.
In questo processo si è visto come nel mondo .NET esistono tre modi diversi per allocare la memoria a seconda delle necessità: di stack, nell'heap non gestito, nell'heap gestito. Quest'ultimo è quello che usiamo più abitualmente ed è fatto di oggetti creati con la parola chiave new oppure di array. A seconda del tipo di allocazione, però, dobbiamo scorrere e modificare i byte in modi differenti.
Mediante l'introduzione di un nuovo pacchetto NuGet System.Memory attualmente in prerelease, invece, possiamo ora uniformare l'accesso e ottimizzare l'uso della memoria evitando inutili allocazioni. Installato il pacchetto vengono forniti due tipi ReadOnlySpan<T> e Span<T> rispettivamente per leggere o per leggere e modificare una sequenza. Disponiamo, inoltre, di extension method per agevolarci nelle conversioni, per esempio da una stringa.
// Crea uno span sulla base di una stringa // cioè di un array di char ReadOnlySpan<char> stringaSpan = "Questa è una stringa".AsSpan();
La funzione Slice, tra le più interessanti, restituisce un nuovo ReadOnlySpan<T>, una struct di basso impatto, che si riferisce sempre alla medesima area di memoria o ad un suo sottoinsieme, senza quindi creare nuovi array o nuove stringhe.
// Stampa 6 Console.WriteLine(stringaSpan.Length); // Stampa false Console.WriteLine(stringaSpan.IsEmpty); // Converto in un nuovo array string questaString = new string(questaSpan.ToArray()); Console.WriteLine(questaString);
Partendo da un array o da allocazioni non gestite, possiamo creare uno Span<T> e proseguire quindi a travasi o a manipolazioni.
char[] charArray = "Questa è una stringa".ToCharArray(); // Span dall'array, modifabile Span<char> stringa2Span = new Span<char>(charArray); // Errore a runtime, troppo piccolo "Quella non".AsSpan().CopyTo(stringa2Span.Slice(0, 6)); // Copio in uno spazio sufficiente "quella".AsSpan().CopyTo(stringa2Span.Slice(0, 6)); Span<byte> bytesSpan = stringa2Span.AsBytes(); // Cambio il primo carattere in "Q" maiuscolo. In unicode sono due byte bytesSpan[0] = 81; bytesSpan[1] = 0; // Converto in un array char[] charArray2 = stringa2Span.ToArray(); // Stampa false, viene ottenuta una nuova allocazione Console.WriteLine(Object.ReferenceEquals(charArray, charArray2)); // Stampa "Quella è una stringa" dall'array originale string questaString2 = new string(charArray); Console.WriteLine(questaString2);
Nell'esempio viene mostrato come sia anche possibile passare ad interpretazioni di tipo diverso, pur manipolando sempre la stessa area di memoria.
L'uso di questa struttura, quindi, è l'ideale quando dobbiamo analizzare o manipolare sequenze di aree di memoria. E' prevista anche l'introduzione di un Memory<T>, una sorta di factory per Span<T>, utile per interfacciarsi anche con Stream, ma al momento non risulta ancora disponibile. Per maggiori dettagli rimandiamo alla issue dedicata allo sviluppo.
https://github.com/dotnet/coreclr/issues/5851
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Gestione dell'annidamento delle regole dei layer in CSS
Utilizzare gRPC su App Service di Azure
Inference di dati strutturati da testo con Semantic Kernel e ASP.NET Core Web API
Recuperare automaticamente un utente e aggiungerlo ad un gruppo di Azure DevOps
Utilizzare Container Queries nominali
Creare un webhook in Azure DevOps
Generare velocemente pagine CRUD in Blazor con QuickGrid
Selettore CSS :has() e i suoi casi d'uso avanzati
Utilizzare DeepSeek R1 con Azure AI
Creare una libreria CSS universale: Nav menu
Migliorare la sicurezza dei prompt con Azure AI Studio
Creare una libreria CSS universale - Rotazione degli elementi