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 Maschinenbefehle übersetzt werden, die CPUs ausführen, anstatt in regulären Bytecode, mit 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 schwere 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 dem nativen Code!")

Dies aktiviert die Native Code-Generierung für alle Funktionen im Skript und den obersten Geltungsbereich, wenn dies als vorteilhaft erachtet wird. Es sind keine zusätzlichen Änderungen erforderlich; das Verhalten der nativ ausführenden Skripte ist genau dasselbe 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 auf Tabellen und insbesondere buffer-Typen haben, könnte das Skript ein guter Kandidat sein.

  • Nur die Funktionen des Skripts werden nativ kompiliert. Der Code im obersten äußeren Geltungsbereich wird oft nur einmal ausgeführt und profitiert nicht so sehr wie Funktionen, die viele Male aufgerufen werden, insbesondere solche, 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, sie zu verwenden. Das Script Profiler Tool kann die Leistung von Funktionen messen, um fundierte Entscheidungen zu treffen.

  • Es kann 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 der Server erhöhen kann.
    • Zusätzlicher Speicher wird benötigt, um nativ kompilierten Code zu speichern.
    • Es gibt eine Begrenzung 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

Während alle Funktionen sich gleich verhalten, ob die Native Code-Generierung aktiviert ist oder nicht, werden einige von ihnen nicht nativ ausgeführt und könnten zu De-Optimierungen oder einem Rückfall in die interpretierte Ausführung führen. Dazu gehören:

  • Verwendung der veralteten getfenv()/setfenv() Aufrufe.
  • Verwendung verschiedener Luau-Builtin-Funktionen wie math.asin() mit nicht-numerischen Argumenten.
  • Übergeben von falsch typisierten Parametern an typisierte Funktionen, zum Beispiel foo(true) aufzurufen, wenn foo als function foo(arg: string) deklariert ist. Denken Sie daran, immer die richtigen Typannotationen zu verwenden.

Wenn Sie den 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 markiert nicht nativ zu sein scheint, könnten ein oder mehrere Faktoren aus der obigen Liste eine De-Optimierung auslösen.

Verwenden Sie Typannotationen

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

Während die Native Code-Generierung jeden Typ unterstützt, können Fehlvorhersagen unnötige Überprüfungen auslösen, was zu einer langsameren Codeausführung führt.

Um einige häufige Probleme zu lösen, werden Luau-Typannotationen für Funktionsargumente überprüft, aber es wird besonders empfohlen, Vector3 Argumente zu annotieren:

--!native
-- "v" wird als Tabelle angenommen; Funktion führt langsamer aus aufgrund von Tabellenüberprüfungen
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- "v" wird als Vector3 deklariert; Code spezialisiert für Vektoren wird generiert
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

Allgemeines Debugging von Skripten wird unterstützt, aber die Ansichten für lokale/Upvalues können unvollständig sein und Variablen aus Call-Stack Frames, die nativ ausgeführt werden, fehlen möglicherweise.

Beachten Sie auch, dass beim Debuggen von Code, der für die native Kompilierung ausgewählt wurde, das Setzen von Breakpoints die native Ausführung für diese Funktionen deaktiviert.

Script Profiler

Im Script Profiler zeigen Funktionen, die nativ ausgeführt werden, <native> neben sich an:

Beispiel für native Funktionen, die im Script Profiler gekennzeichnet sind

Wenn eine Funktion, die mit @native markiert ist oder sich in einem --!native Skript befindet, nicht die <native> Annotation zeigt, wird diese Funktion möglicherweise nicht nativ ausgeführt, aufgrund von Breakpoint Platzierung, Verwendung von vermeidbarem Code oder nicht übereinstimmenden Typannotationen.

Luau Heap

Im Luau Heap Profiler wird der Speicher, der von nativen Funktionen verwendet wird, als [native] Elemente im Diagramm angezeigt.

Beispiel für die native Speichernutzung, die im Luau Heap Profiler gekennzeichnet ist

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. Dies macht es unerlässlich, 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-Modus über den Client/Server-Umschalter befinden.
  2. Rufen Sie debug.dumpcodesize() aus der Befehlszeile auf.

Im Output Fenster sehen Sie die Gesamtzahl der Skripte und Funktionen, die bis zum Zeitpunkt des Aufrufs nativ kompiliert wurden, den Speicher, der von ihrem nativen Code verbraucht wird, und die native Codegrößenbeschränkung. Nach der Zusammenfassung sehen Sie eine Tabelle für jedes nativ kompilierte Skript in absteigender Reihenfolge der Codegröße.

Beispiel für die native Codegröße, die im Output-Fenster angezeigt wird.

Für jedes Skript zeigt die Ausgabe die Anzahl der kompilierten Funktionen und den Speicherverbrauch des nativen Codes an. Jede Funktion wird dann in absteigender Reihenfolge der nativen Codegröße aufgelistet, wobei anonyme Funktionen als [anonymous] und gesamte Skripte als [top level] angezeigt werden. In der letzten Spalte wird der Prozentsatz in Bezug auf die native Codegrößenbeschränkung berechnet. Beachten Sie, dass die native Codegröße von Funktionen genau gemeldet wird, aber der Speicherverbrauch für Skripte auf die nächste Seitenzahl gerundet wird.

Grenzen und Fehlersuche

Das Kompilieren von Code in Anweisungen für eine bestimmte CPU erfordert zusätzlichen Speicherplatz. Darüber hinaus kann die Optimierung komplexer Funktionen zu viel Zeit in Anspruch nehmen. Das Erreichen einer internen Grenze wird einen Fehler im Studio-Fenster Output melden, einschließlich:

Funktion 'f' in Zeile 20 hat die Grenze für einzelne 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 Grenze 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 Kontrollflussblöcken in Ihrem Skript überein, aber dieser Fehler kann vermieden werden, indem der Kontrollfluss in der Funktion vereinfacht oder in einzelne kleinere Funktionen aufgeteilt wird.

Funktion 'f' in Zeile 200 hat die Gesamtgrenze für 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 kann von Funktionen früher im Skript erreicht worden sein. 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 anzuwenden. Sie können auch versuchen, dieses separate Skript mit --!native zu kennzeichnen, aber 1 Million Anweisungen benötigt viel Speicher und Sie könnten die Speicherkapazität überschreiten.

Funktion 'f' in Zeile 20 hat einen internen Fehler beim Senken festgestellt (oder)
Interner Fehler: Native Code-Generierung fehlgeschlagen (Assembly-Senkung)

Manchmal enthält eine Funktion komplexe Codeabschnitte, 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 Fehlerbericht 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, damit mehr kleinere Skripte unter die Grenze passen. Alternativ können Sie große oder selten aufgerufene Funktionen in ein separates nicht-natives Modul verschieben.

©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.