Novità in .Net 8 . Microsoft .NET 8 sarà rilasciato ufficialmente molto presto, nel novembre 2023. Designata come versione LTS (Long Term Support), garantisce un supporto continuo, aggiornamenti e correzioni di bug per un minimo di tre anni dal lancio. Questo impegno consente agli sviluppatori di adottare questa nuova versione con fiducia. .NET 8 diventerà la versione predefinita per molte organizzazioni nei prossimi due anni.
Sulla base dei cambiamenti introdotti in .NET 7, questa versione aggiunge ulteriori miglioramenti. Scopriamo le 10 principali novità di .NET 8.
Prestazioni, prestazioni, prestazioni (Novità in .Net 8)
Ancora una volta Microsoft ha impegnato una notevole quantità di risorse per migliorare le prestazioni del suo nuovo .NET 8. E come al solito Stephen Toub ha redatto un articolo esaustivo, lungo centinaia di pagine, che riassume tutti questi miglioramenti: Performance Improvements in .NET 8.
Ecco tre miglioramenti chiave delle prestazioni che mi hanno colpito:
Il metodo List.AddRange(IEnumerable) è stato riscritto per ottenere prestazioni migliori quando la sequenza non è una ICollection.

Le prestazioni di Int32.ToString() sono state migliorate grazie alla memorizzazione nella cache dei valori di stringa da 0 a 299. Inoltre, gli ingegneri di .NET hanno dimezzato il numero di divisioni. Questa riduzione deriva dal dividere per 100 per ottenere due cifre, invece di dividere per 10 per ottenere una singola cifra.

Su macOS, File.Copy() ha migliorato notevolmente la sua velocità affidandosi alla funzione clonefile del sistema operativo, se disponibile, per il processo di copia.

Nuova funzione DATAS (Dynamic Adaptation To Application Sizes) della Garbage Collection di Novità in .Net 8
Il GC di .NET 8 introduce la funzione DATAS (Dynamic Adaptation To Application Sizes). Esso regola l’utilizzo della memoria dell’applicazione in base alle dimensioni dei dati vivi (LDS), che comprendono i dati a lunga durata e i dati in volo durante un evento GC. DATAS ha due casi d’uso principali:
È utile per carichi di lavoro intensivi in ambienti con vincoli di memoria, come le applicazioni containerizzate con limiti di memoria. DATAS riduce o espande la dimensione dell’heap secondo le necessità.
È utile per i piccoli carichi di lavoro che utilizzano Server GC, garantendo che la dimensione dell’heap sia in linea con i requisiti effettivi dell’applicazione.
Sebbene alcuni lo abbiano inizialmente definito “il GC dinamico”, l’obiettivo principale di DATAS è quello di adattarsi alle dimensioni dell’applicazione. Il GC è sempre stato dinamico, ma DATAS lo mette a punto per adattarsi meglio ai carichi di lavoro in .NET.
Serializzazione e deserializzazione System.Text.Json
In .NET 8, System.Text.Json offre una serie di aggiornamenti interessanti per gli sviluppatori. Questa release migliora l’esperienza dell’utente nelle applicazioni native AOT (Ahead-Of-Time) grazie a numerosi miglioramenti sul generatore di sorgenti, tra cui:
- Supporto della serializzazione di tipi con proprietà required e init.
- Attributo JsonSourceGenerationOptions: Si allinea con JsonSerializerOptions, consentendo la configurazione della serializzazione in tempo di compilazione.
- Gestione migliorata dei tipi: Ignora le proprietà inaccessibili, consente la nidificazione delle dichiarazioni di JsonSerializerContext e gestisce dinamicamente i tipi generati dal compilatore.
- JsonStringEnumConverter: Un nuovo tipo di convertitore semplifica la serializzazione degli enum nelle applicazioni AOT native.
- Inoltre, la proprietà JsonConverter.Type aiuta a recuperare il tipo di un’istanza JsonConverter non generica, con supporto nullable per vari scenari.
Sono presenti molti altri miglioramenti, tra cui:
- JsonNamingPolicy incorpora ora nuove politiche di denominazione per la conversione dei nomi delle proprietà in snake_case (con trattini bassi) e kebab-case (con trattini).
- È ora possibile deserializzare i dati su campi di sola lettura o proprietà di sola lettura, ovvero quelli senza un accessor set.
- È ora possibile scegliere di disabilitare il serializzatore basato sulla riflessione come opzione predefinita. Questa possibilità è utile per evitare l’inclusione involontaria di componenti di riflessione, in particolare nelle applicazioni trimmed e Native AOT.
Nuove comode API per la gestione della randomness (Novità in .Net 8)
.NET 8 svela metodi rivoluzionari per rivoluzionare il nostro approccio alla casualità. Ciò è particolarmente utile per le applicazioni di apprendimento automatico. Ad esempio, i nuovi metodi System.Random.GetItems() e System.Security.Cryptography.RandomNumberGenerator.GetItems() consentono di selezionare un numero specifico di elementi in modo casuale da un insieme di input:
casualità net8.0
I nuovi metodi Random.Shuffle e RandomNumberGenerator.Shuffle(Span) consentono ora di randomizzare l’ordine di un intervallo. Questi metodi sono utili per attenuare le distorsioni di formazione nell’apprendimento automatico (quindi il primo elemento non è necessariamente di formazione e l’ultimo non è necessariamente di test).
net8.0 rimescola
Nuova API di astrazione del tempo
La nuova classe TimeProvider e l’interfaccia ITimer offrono funzionalità di astrazione del tempo, facilitando la simulazione del tempo negli scenari di test. TimeProvider è una classe astratta con numerose funzioni virtuali, che la rendono un candidato ideale per l’integrazione con i framework di mocking. Ciò consente di eseguire il mocking di tutti i suoi aspetti senza soluzione di continuità e in modo completo. Ad esempio:
static DateTimeOffset AddNDaysToUtcNow(TimeProvider timeProvider, int nbDays) {
return timeProvider.GetUtcNow().AddDays(nbDays);
}
[Test]
public void Test_AddNDaysToNow() {
var ttp = new TestTimeProvider(new DateTimeOffset(new DateTime(2023,10,30,0,0,0)));
var result = AddNDaysToUtcNow(ttp, 5);
Assert.IsTrue(result.Year == 2023);
Assert.IsTrue(result.Month == 11);
Assert.IsTrue(result.Day == 4);
}
class TestTimeProvider : TimeProvider {
private readonly DateTimeOffset m_UtcNow;
public TestTimeProvider(DateTimeOffset utcNow) { this.m_UtcNow = utcNow; }
public override DateTimeOffset GetUtcNow() { return m_UtcNow; }
}
Sottolineiamo questa osservazione di un ingegnere Microsoft:
“In fin dei conti, ci aspettiamo che quasi nessuno utilizzi qualcosa di diverso da TimeProvider.System nell’uso di produzione”. A differenza di molte astrazioni, questa è speciale: esiste solo per la testabilità”.
Si noti che è possibile utilizzare l’astrazione temporale anche per simulare operazioni di Task che dipendono dalla progressione temporale, come Task.Delay() e Task.WaitAsync().
Queste astrazioni temporali erano molto attese, dopo anni di dibattiti e discussioni.
Nuovi tipi che possono migliorare le prestazioni in varie situazioni
.NET 8 offre il nuovo spazio dei nomi System.Collections.Frozen. Esso contiene le nuove classi di collezioni FrozenSet e FrozenDictionary. Il qualificatore Frozen significa che le collezioni sono immutabili: non possono essere modificate una volta create. Internamente, l’implementazione sfrutta questo requisito per consentire un’enumerazione più rapida e operazioni di ricerca più veloci, come Contains() o TryGetValue(). Queste nuove collezioni congelate si rivelano particolarmente preziose in scenari in cui le collezioni vengono inizialmente popolate e successivamente mantenute per l’intero ciclo di vita di un’applicazione longeva.
List list = [1, 2, 3, 4];
FrozenSet frozenSet = list.ToFrozenSet();
Assert.IsTrue(frozenSet.Contains(4)); // Faster because the set is immutable
HashSet hashSet = list.ToHashSet();
hashSet.Add(5);
Assert.IsTrue(hashSet.Contains(2)); // Slower because we can modify the set
- La nuova classe System.Buffers.SearchValues è ottimizzata per gli scenari in cui un insieme coerente di valori viene spesso utilizzato per le ricerche in runtime, come ad esempio nell’implementazione di String.IndexOfAny(char[]). Quando si crea un’istanza di SearchValues, tutti i dati essenziali necessari per ottimizzare le ricerche future vengono calcolati in anticipo, semplificando il processo.
- La nuova classe System.Text.CompositeFormat si rivela preziosa per ottimizzare le stringhe di formato, come “Nome:{0} Cognome: {1}”, non note al momento della compilazione. Sebbene vi sia un sovraccarico iniziale in attività come l’analisi delle stringhe, questo approccio proattivo riduce significativamente il carico computazionale negli usi successivi, migliorando le prestazioni e l’efficienza.
UTF8 Formatting
Per consentire la generazione di una rappresentazione simile a una stringa del proprio tipo in uno span di destinazione, implementare l’interfaccia IUtf8SpanFormattable, introdotta di recente, per il proprio tipo:
public interface IUtf8SpanFormattable {
bool TryFormat(Span utf8Destination, out int bytesWritten, ReadOnlySpan format, IFormatProvider? provider);
}
Questa interfaccia è simile a ISpanFormattable. È progettata specificamente per UTF-8 e Span, al contrario di UTF-16 e Span.
In .NET 8 tutti i tipi primitivi (e non solo) implementano questa interfaccia: Byte, Complex, Char, DateOnly, DateTime, DateTimeOffset, Decimal, Double, Guid, Half, IPAddress, IPNetwork, Int16, Int32, Int64, Int128, IntPtr, NFloat, SByte, Single, Rune, TimeOnly, TimeSpan, UInt16, UInt32, UInt64, UInt128, UIntPtr e Version.
Metodi ZipFile basati sul flusso
È ora possibile comprimere i file da una directory utilizzando un flusso senza doverli memorizzare in un file temporaneo. Ciò consente di gestire direttamente il risultato della compressione in memoria. Queste nuove API si rivelano utili negli scenari in cui lo spazio su disco è limitato, in quanto eliminano la necessità di utilizzare il disco come passaggio intermedio. Ecco le nuove API:
namespace System.IO.Compression;
public static partial class ZipFile
{
public static void CreateFromDirectory(string sourceDirectoryName, Stream destination);
public static void CreateFromDirectory(string sourceDirectoryName, Stream destination, CompressionLevel compressionLevel, bool includeBaseDirectory);
public static void CreateFromDirectory(string sourceDirectoryName, Stream destination, CompressionLevel compressionLevel, bool includeBaseDirectory, Encoding? entryNameEncoding);
public static void ExtractToDirectory(Stream source, string destinationDirectoryName) { }
public static void ExtractToDirectory(Stream source, string destinationDirectoryName, bool overwriteFiles) { }
public static void ExtractToDirectory(Stream source, string destinationDirectoryName, Encoding? entryNameEncoding) { }
public static void ExtractToDirectory(Stream source, string destinationDirectoryName, Encoding? entryNameEncoding, bool overwriteFiles) { }
}
Supporto del set di istruzioni Intel AVX-512
.NET Core 3.0 ha proposto il supporto per SIMD incorporando API intrinseche all’hardware specifiche della piattaforma per x86/x64. Successivamente, .NET 5 ha esteso il supporto ad Arm64 e con l’avvento di .NET 7 sono state introdotte le intrinseche hardware multipiattaforma. .NET 8 migliora ulteriormente le capacità SIMD introducendo Vector512 ed estendendo il supporto alle istruzioni Intel Advanced Vector Extensions 512 (AVX-512).
In particolare, .NET 8 introduce il supporto per le seguenti caratteristiche chiave di AVX-512:
- Operazioni vettoriali a 512 bit.
- 16 registri SIMD aggiuntivi.
- Istruzioni aggiuntive disponibili per vettori a 128, 256 e 512 bit.
Inoltre, anche senza utilizzare esplicitamente istruzioni specifiche per Vector512 o Avx512F nel codice, è probabile che si tragga vantaggio dal supporto AVX-512 migliorato. Il compilatore JIT può sfruttare i registri e le istruzioni extra in modo implicito quando si usa Vector128 o Vector256.
Infine, si noti che se si dispone di hardware compatibile con AVX-512, Vector512.IsHardwareAccelerated restituirà ora true.
Crittografia
.NET 8 propone ora il supporto per le primitive di hashing SHA-3. SHA-3 è attualmente compatibile con Linux con OpenSSL 1.1.1 o successivo e con Windows 11 Build 25324 o successivo. Le API esistenti che offrono SHA-2 includono ora le loro controparti SHA-3 che comprendono SHA3_256, SHA3_384 e SHA3_512 per l’hashing; HashAlgorithmName.SHA3_256, HashAlgorithmName.SHA3_384 e HashAlgorithmName. SHA3_512 per l’hashing in cui l’algoritmo è configurabile; HMACSHA3_256, HMACSHA3_384 e HMACSHA3_512 per HMAC; e RSAEncryptionPadding.OaepSHA3_256, RSAEncryptionPadding.OaepSHA3_384 e RSAEncryptionPadding.OaepSHA3_512 per la crittografia RSA OAEP.
Conclusioni – Novità in .Net 8
Riassumendo, .NET 8 rappresenta un sostanziale balzo in avanti, introducendo tante nuove funzionalità e miglioramenti. Le nuove API e funzionalità sono adatte a garantire la competitività e la sicurezza del vostro codice nei prossimi tre anni.
(fonte)
Innovaformazione, scuola informatica specialistica promuove la cultura IT e gli aggiornamenti fra gli sviluppatori.
Nell’offerta formativa per aziende trovate l’elenco corsi in ambito Microsofot .Net QUI.
INFO: info@innovaformazione.net – tel. 3471012275 (Dario Carrassi)
Vuoi essere ricontattato? Lasciaci il tuo numero telefonico e la tua email, ti richiameremo nelle 24h:
Articoli correlati
CancellationToken in .NET
Spieghiamo Graph Neural Networks GNNs
Cosa è SAP Business Objects
Mappa delle Aziende che usano SAP in Italia
Guida Oracle APEX
