Programmierung und Softwareentwicklung

Die Verbesserungen in .NET 11 summieren Leistungsgewinne vom JIT bis zur asynchronen Programmierung

Microsoft stellt Hunderte Verbesserungen in .NET 11 vor, mit einem klaren Schwerpunkt auf dem JIT-Compiler, der Verringerung von Allokationen sowie der Optimierung von Schnittstellen- und Delegataufrufen und der internen Struktur von async/await. Die veröffentlichten Ergebnisse zeigen, dass die Gewinne durch das Entfernen unnötiger Prüfungen, Allokationen und Aufrufe entstehen – nicht durch eine einzige große Änderung.

2026-09-15
5 Min. Lesezeit
6 Aufrufe
فريق تحرير certi.news
Die Verbesserungen in .NET 11 summieren Leistungsgewinne vom JIT bis zur asynchronen Programmierung

Microsoft stellt in einem am 15. September 2026 im .NET Blog veröffentlichten Beitrag Hunderte Verbesserungen vor, die in .NET 11 eingeflossen sind, und präsentiert sie als kumulatives Ergebnis langjähriger Arbeit am Just-in-Time-Compiler (JIT), an der Laufzeit und an den Bibliotheken. Die zentrale Idee ist nicht, dass eine einzelne Funktion die Leistung verdoppelt, sondern dass sich viele kleine, wiederkehrende Gewinne summieren: eine nicht mehr erforderliche Bereichsprüfung, eine entfernte Speicherallokation, eine vermiedene Sperre oder ein vermiedener Systemaufruf sowie Schleifen, die mit weniger Prozessortaktzyklen ausgeführt werden.

Die Bedeutung dieser Art von Verbesserungen besteht darin, dass ein großer Teil davon keine Anpassung oder Neugestaltung des Anwendungscodes erfordert. Der JIT-Compiler wandelt den normalerweise von C#, F# und Visual Basic erzeugten IL-Zwischencode in native Anweisungen um, die der Prozessor ausführt. Wenn er nachweisen kann, dass ein virtueller Aufruf auf einen bestimmten Typ ausgerichtet werden kann oder dass eine bestimmte Prüfung nicht fehlschlagen wird, kann er kürzere Anweisungen erzeugen und die Chancen erhöhen, Funktionen ineinander einzubetten.

Verbesserung der Abstraktionsentfernung

Ein herausragender Teil des Beitrags konzentriert sich auf das, was Microsoft als Abstraktionsentfernung bezeichnet, also darauf, der Laufzeit zu ermöglichen, die Ausführungskosten bestimmter Abstraktionen zu umgehen, die Entwickler beim Entwurf eines Programms benötigen. Beispiele sind Schnittstellen- und virtuelle Methodenaufrufe, bei denen die herkömmliche Ausführung mehrere Zeiger laden und einen indirekten Aufruf durchführen muss, was das Einbetten der aufgerufenen Funktion in die aktuelle Funktion verhindert.

.NET 11 entwickelt den Ansatz der „Guarded Devirtualization“ weiter. Der JIT erkennt den häufigsten Typ während der Ausführung, erstellt einen schnellen Pfad für den direkten Aufruf und behält gleichzeitig den virtuellen Pfad bei, um die korrekte Ausführung sicherzustellen, falls später ein anderer Typ auftritt. Wenn dadurch das Einbetten der Funktion möglich wird, werden weitere Optimierungen wie das Weiterreichen von Konstanten, das Entfernen von Verzweigungen und Bereichsprüfungen möglich.

Die Arbeit erstreckt sich auf allgemeine virtuelle Methoden, ReadyToRun- und NativeAOT-Vorgänge sowie auf virtuelle Implementierungen in Schnittstellen. Der Beitrag weist darauf hin, dass diese Verbesserungen die Codegröße erhöhen können, wenn direkte Aufrufe zu mehr Einbettungen führen, sie machen die Programmlogik jedoch für den Optimierer besser sichtbar.

Weniger Allokationen und geringere Belastung des Garbage Collectors

.NET 11 baut außerdem die Escape Analysis weiter aus. Dabei wird versucht festzustellen, ob ein innerhalb einer Funktion erzeugtes Objekt deren Gültigkeitsbereich verlässt. Wenn nachgewiesen ist, dass es diesen Bereich nicht verlässt, kann der JIT vermeiden, es auf dem verwalteten Heap abzulegen, oder die Allokation in manchen Fällen vollständig beseitigen, wodurch der Druck auf den Garbage Collector sinkt.

Die Quelle zeigt Beispiele für eine verbesserte Behandlung des Boxings nullable Werte und für eine bedingte Escape-Analyse bei der Aufzählung von Sammlungen. In einer Messung verschwand eine 32 Byte große Allokation beim Aufzählen einer aus einem Instanzfeld erstellten Sammlung, und die Ausführungszeit sank von 13,874 Nanosekunden in .NET 10 auf 2,674 Nanosekunden in .NET 11. Außerdem können einige Fälle, in denen allgemeine Werte oder Schnittstellenaufrufe verwendet werden, temporäre Allokationen von 24 Byte vermeiden.

Diese Zahlen beziehen sich auf sehr kleine Vorgänge und sollten daher nicht als allgemeine, konstante Leistungssteigerung für jede Anwendung verstanden werden. Ihr wichtigster Nutzen besteht darin, Muster im Code sichtbar zu machen, die die Laufzeit optimieren kann; die tatsächlichen Auswirkungen hängen dagegen von der Art der Anwendung und ihren Hotpaths ab.

Delegaten und die asynchrone Laufzeit

.NET 11 enthält Änderungen an der Darstellung von Delegaten in CoreCLR, darunter das Entfernen eines feldgroßen Zeigers aus jedem Delegatenobjekt bei einem 64-Bit-Prozess, was dem Beitrag zufolge 8 Byte pro Delegat einspart. Außerdem wurden die Felder der Delegatendarstellung in NativeAOT neu angeordnet, und einige gemeinsam verwendete Werte wurden im Speicher zusammengelegt, um den Zugriff auf Architekturen wie Arm64 zu verbessern.

Der Blogbeitrag stellt außerdem eine neue Struktur unter der Bezeichnung „runtime async“ vor, die einen Teil der Umwandlung von async/await-Methoden vom C#-Compiler auf den JIT und die Laufzeit verlagert. Beim herkömmlichen Modell erzeugt der Compiler eine Zustandsmaschine mit den für die Fortsetzung erforderlichen Feldern, etwa Parametern, lokalen Werten, Awaitern und dem Ausführungsstatus. Das neue Modell verwendet dagegen einen kleineren Vertrag im IL und überlässt anschließend der Laufzeit und dem JIT Entscheidungen darüber, welche Werte an Unterbrechungspunkten noch aktiv sind, wie Fortsetzungsobjekte angeordnet werden und wie das nach außen sichtbare Task- oder ValueTask-Objekt erstellt wird.

Was ändert sich in der Praxis?

Die redaktionelle Kernaussage dieser Runde lautet, dass .NET 11 stärker auf die Optimierung vorhandenen Codes setzt als auf das Hinzufügen neuer Programmierschnittstellen. Anwendungen, die intensiv Schnittstellen, generische Methoden, Delegaten, Aufzählungen und asynchrone Vorgänge verwenden, können ohne direkte Änderungen am Quellcode profitieren; das Ausmaß der Verbesserung variiert jedoch je nach Prozessor, Betriebssystem, Laufzeiteinstellungen und Art der Arbeitslast.

Microsoft empfiehlt, die Ergebnisse mit BenchmarkDotNet zu testen, .NET 10 und .NET 11 zu installieren und denselben Code auf beiden Versionen auszuführen. Das Unternehmen weist darauf hin, dass die veröffentlichten Messungen sehr präzise Tests sind und durch Hardware, andere Prozesse und Umgebungseinstellungen beeinflusst werden können. Daher reichen die Ergebnisse eines Mikrobenchmarks nicht aus, um eine Upgradeentscheidung zu treffen oder eine umfassende Verbesserung zu belegen; vor weitergehenden Schlussfolgerungen müssen die tatsächlichen Anwendungslasten gemessen werden.

Nachrichtenquelle
ف
Autor

فريق تحرير certi.news

Aus derselben Kategorie

Das könnte Sie interessieren

Alle Nachrichten anzeigen