Native-Code-Generierung

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

Mit der Luau-Unterstützung für die Native-Code-Generierung können serverseitige Skripte in Ihrem Spiel direkt in die Maschinencode-Anweisungen kompiliert werden, die von CPUs ausgeführt werden, anstatt in regulärem Bytecode, auf dem die Luau-VM arbeitet. Diese Funktion kann verwendet werden, um die Ausführungsgeschwindigkeit für einige Skripte auf dem Server zu verbessern, insbesondere für solche, die viele numerische Berechnungen durchführen, ohne zu viele umfangreiche Luau-Bibliotheks- oder Roblox-API-Aufrufe zu verwenden.

Aktivieren der Native-Code-Generierung

Um die Native-Code-Generierung für ein Script zu aktivieren, fügen Sie den --!native-Kommentar oben hinzu:¹


--!native
print("Hallo aus native code!")

Dies aktiviert die Native-Code-Generierung für alle Funktionen im Skript und den übergeordneten Geltungsbereich, wenn es als vorteilhaft angesehen wird. Es sind keine zusätzlichen Änderungen erforderlich; das Verhalten der nativ ausgeführten Skripte ist genau das gleiche wie zuvor und nur die Leistung ist unterschiedlich. Alle Funktionen der Luau-Sprache und alle Roblox-APIs bleiben unterstützt.

Alternativ können Sie die Native-Code-Generierung für eine einzelne Funktion aktivieren, indem Sie das @native-Attribut hinzufügen:


@native
local function f(x)
return (x + 1)
end
1 In Zukunft könnten einige Skripte automatisch nativ ausgeführt werden, wenn festgestellt wird, dass dies vorteilhaft ist, aber manuell platzierte --!native-Kommentare sind derzeit erforderlich.

Best Practices

Die folgenden Tipps helfen Ihnen, am meisten von der Native-Code-Generierung zu profitieren:

  • Es ist am besten, diese Funktion in Skripten zu aktivieren, die viele Berechnungen direkt in Luau durchführen. Wenn Sie viele mathematische Operationen an Tabellen, insbesondere buffer-Typen, haben, könnte das Skript ein guter Kandidat sein.

  • Nur die Funktionen des Skripts werden nativ kompiliert. Der Code im übergeordneten Geltungsbereich wird oft nur einmal ausgeführt und profitiert nicht so sehr von Funktionen, die viele Male aufgerufen werden, insbesondere von denen, die in jedem Frame aufgerufen werden.

  • Es wird empfohlen, die Zeit zu messen, die ein Skript oder eine Funktion mit und ohne native Kompilierung benötigt, um zu beurteilen, wann es am besten ist, es zu verwenden. Das Script Profiler-Werkzeug kann die Leistung von Funktionen messen, um fundierte Entscheidungen zu treffen.

  • Es könnte verlockend sein, den --!native-Kommentar in jedem Skript zu platzieren, nur für den Fall, dass einige von ihnen schneller ausgeführt werden, aber die Native-Code-Generierung hat einige Nachteile:

    • Die Kompilierungszeit des Codes ist erforderlich, was die Startzeit von Servern erhöhen kann.
    • Es wird zusätzlicher Speicher benötigt, um nativ kompilierten Code zu speichern.
    • Es gibt eine Grenze für die insgesamt erlaubte Menge an nativ kompiliertem Code in einem Spiel.

Diese Probleme können durch einen überlegten Einsatz des @native-Attributs angegangen werden.

Zu vermeidender Code

Obwohl alle Funktionen gleich funktionieren, unabhängig davon, ob die Native-Code-Generierung aktiviert ist oder nicht, werden einige von ihnen nicht nativ ausgeführt und könnten eine De-Optimierung oder einen Rückfall in die interpretierte Ausführung verursachen. Dazu gehören:

  • Verwendung der veralteten Aufrufe getfenv()/setfenv().
  • Verwendung verschiedener integrierter Luau-Funktionen wie math.asin() mit nicht-numerischen Argumenten.
  • Übergeben von nicht richtig typisierten Parametern an typisierte Funktionen, z. B. das Aufrufen von foo(true), wenn foo als function foo(arg: string) deklariert ist. Denken Sie daran, immer die richtigen Typanmerkungen zu verwenden.

Wenn Sie das Script Profiler verwenden, können Sie die Zeit vergleichen, die eine reguläre Version der Funktion im Vergleich zu der nativ kompilierten Version benötigt. Wenn eine Funktion innerhalb eines --!native-Skripts oder mit @native gekennzeichnet nicht nativ auszuführen scheint, kann einer oder mehrere Faktoren aus der obigen Liste eine De-Optimierung auslösen.

Verwenden von Typanmerkungen

Die Native-Code-Generierung versucht, den wahrscheinlichsten Typ für eine gegebene Variable abzuleiten, um die Codepfade zu optimieren. Zum Beispiel wird angenommen, dass a + b auf Zahlen ausgeführt wird, oder dass auf eine Tabelle in t.X zugegriffen wird. Angesichts der Operatorüberladung könnten a und b jedoch Tabellen oder Vector3-Typen sein, oder t könnte ein Roblox-Datentyp sein.

Obwohl die Native-Code-Generierung jeden Typ unterstützt, können Fehlvorhersagen unnötige Überprüfungen auslösen, die zu langsamerer Codeausführung führen.

Um einige häufige Probleme zu lösen, werden Luau-Typanmerkungen bei Funktionsargumenten überprüft, es wird jedoch insbesondere empfohlen, Vector3-Argumente zu annotieren:


--!native
-- "v" wird als Tabelle angesehen; Funktion führt langsamer aufgrund der Tabellenüberprüfungen aus
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- "v" wird als Vektor3 deklariert; Code für Vektoren optimiert
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
end

Studio-Tools

Die folgenden Studio-Tools werden für --!native-Skripte und @native-Funktionen unterstützt.

Debugging

Allgemeine Fehlerbehebung von Skripten wird unterstützt, aber die Ansichten für Locals/Upvalues könnten unvollständig sein und Variablen aus Call-Stack-Frames, die nativ ausgeführt werden, fehlen.

Bitte beachten Sie auch, dass das Platzieren von Breakpoints beim Debuggen von Code, der für die native Kompilierung ausgewählt wurde, die native Ausführung dieser Funktionen deaktiviert.

Script Profiler

Im Script Profiler wird nativ ausgeführenden Funktionen <native> neben ihnen angezeigt:

Beispiel für nativ gekennzeichnete Funktionen im Script Profiler

Wenn eine mit @native markierte Funktion oder eine in einem --!native-Skript enthaltene Funktion nicht die <native>-Kennzeichnung zeigt, dann könnte diese Funktion aufgrund von Breakpoint-Setzungen, Verwendung von weniger empfehlenswertem Code oder nicht übereinstimmenden Typanmerkungen nicht nativ ausgeführt werden.

Luau Heap

Im Luau Heap-Profiler wird der Speicher, der von nativ ausgeführten Funktionen verwendet wird, als [native]-Elemente im Diagramm angezeigt.

Beispiel für nativ gekennzeichneten Speicherverbrauch im Luau Heap-Profiler

Größenanalyse

Jedes nativ kompilierte Skript verbraucht Speicher. Wenn die Größe des kompilierten Codes eine vordefinierte Grenze erreicht, stoppt die native Kompilierung und der verbleibende Code wird nicht nativ ausgeführt. Es ist daher wichtig, Skripte sorgfältig für die native Kompilierung auszuwählen.

Um die native Codegröße einzelner Funktionen und Skripte zu überwachen:

  1. Stellen Sie sicher, dass Sie sich im Server-Ansicht durch den Client/Server-Umschalt-Button befinden.
  2. Rufen Sie debug.dumpcodesize() von der Befehlszeile auf.

Im Output-Fenster sehen Sie die Gesamtzahl der Skripte und Funktionen, die bis zu dem Zeitpunkt, an dem Sie aufgerufen haben, nativ kompiliert wurden, den von ihrem nativen Code verbrauchten Speicher und die Größe des nativen Codes. Nach der Zusammenfassung sehen Sie eine Tabelle für jedes nativ kompilierte Skript in absteigender Reihenfolge der Codegröße.

Beispiel für die angezeigte native Codegröße im Output-Fenster.

Für jedes Skript zeigt die Ausgabe die Anzahl der kompilierten Funktionen und den nativen Code-Speicherverbrauch an. Jede Funktion wird dann in absteigender Reihenfolge der nativen Codegröße aufgeführt, wobei anonyme Funktionen als [anonymous] und gesamte Skripte als [top level] angezeigt werden. In der letzten Spalte wird der Prozentsatz bezüglich der Größe des nativen Codes berechnet. Beachten Sie, dass die native Codegröße der Funktionen genau angegeben wird, der Speicherverbrauch für Skripte jedoch auf die nächstgelegene Seitenkapazität gerundet wird.

Grenzen und Fehlersuche

Das Kompilieren von Code in Anweisungen für eine bestimmte CPU erfordert zusätzlichen Speicherplatz. Darüber hinaus können Optimierungen für komplexe Funktionen zu viel Zeit in Anspruch nehmen. Das Erreichen eines internen Limits wird im Output-Fenster von Studio mit einem Fehler angezeigt, einschließlich:

Funktion 'f' in Zeile 20 hat die Begrenzung einzelner Codeblockanweisungen überschritten

Dieser Fehler bedeutet, dass ein einzelner Block von Code innerhalb einer Funktion mehr als 64K Anweisungen verwendet hat. Dies kann vermieden werden, indem die Funktion vereinfacht oder in einzelne kleinere Funktionen aufgeteilt wird.

Funktion 'f' in Zeile 20 hat die Begrenzung für Funktionscodeblöcke überschritten

Dieser Fehler bedeutet, dass eine einzelne Funktion mehr als 32K interne Codeblöcke enthält. Interne Codeblöcke stimmen nicht genau mit den Steuerflussblöcken in Ihrem Skript überein, aber dieser Fehler kann vermieden werden, indem der Steuerfluss in der Funktion vereinfacht oder in einzelne kleinere Funktionen aufgeteilt wird.

Funktion 'f' in Zeile 200 hat die Gesamtzahl der Modul-Anweisungen überschritten

Dieser Fehler bedeutet, dass die Funktion insgesamt eine Grenze von 1 Million Anweisungen für das gesamte Skript erreicht hat. In einigen Fällen kann die gemeldete Funktion selbst viele Anweisungen haben, oder die Grenze wurde durch Funktionen früher im Skript erreicht. Um dieses Problem zu vermeiden, wird empfohlen, besonders große Funktionen in ein separates nicht-natives Skript zu verschieben oder @native auf die anderen Funktionen zu verwenden. Sie können auch versuchen, dieses separate Skript mit --!native zu kennzeichnen, aber 1 Million Anweisungen belegen viel Speicher und möglicherweise überschreiten Sie die Speicherkapazität.

Funktion 'f' in Zeile 20 hat einen internen Abwärtsfehler erreicht (oder)
Internal error: Native code generation failed (assembly lowering)

Manchmal enthält eine Funktion komplexe Teile von Code, die der Native-Code-Compiler derzeit nicht verarbeiten kann. Um diesen Fehler zu vermeiden, überprüfen Sie komplexe Ausdrücke im Code und teilen Sie sie auf oder vereinfachen Sie sie, ziehen Sie aber auch in Betracht, einen Bugbericht mit einem Beispiel des Codes zu öffnen, der aus diesem Grund fehlgeschlagen ist.

Speicherzuweisungsgrenze für die Native-Code-Generierung erreicht

Dieser Fehler bedeutet, dass die gesamte Speicherkapazität für native Code-Daten erreicht wurde. Um dies zu vermeiden, versuchen Sie, --!native von den speicherintensiveren Skripten zu entfernen, sodass mehr kleinere Skripte unter die Grenze passen. Alternativ verschieben Sie große oder selten aufgerufene Funktionen in ein separates nicht-natives Modul.

©2026 Roblox Corporation. Roblox, das Roblox-Logo und "Powering Imagination" gehören zu unseren eingetragenen und nicht eingetragenen Markenzeichen in den USA und anderen Ländern.