Nativo-Code-Generierung

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

Mit der Unterstützung für nativen Code-Erzeugung kann die serverseitige Skripte in deiner Erfahrung direkt in die Maschinencode-Anweisungen kompiliert werden, die dieCPUs ausführen, anstatt dem üblichen Bytecode, den die Luau-VM aufführt. Diese Funktion kann verwendet werden, um die Ausführungsgeschwindigkeit für einige Skripte auf dem Server zu verbessern, insbesondere diejenigen, die eine Menge numerische Berechnungen ohne den Gebrauch von zu vielen schwerwiegenden Luau-Library

Aktivieren von Native

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


--! native
print("Hello from native code!")

Dies ermöglicht die nativ code generation für alle funktionen im Skript, das. PL: die Skriptsund die top-level scope, wenn sie nützlich angesehen wird. Keine zusätzlichen Änderungen sind erforderlich; das Verhalten der nativ ausführenden Skripte ist genau daselbe wie vorher und nur die leistung ist anders. Alle features der luau-sprache und alle roblox-apis bleiben unterstützt.

Alternativ kannst du die Generierung von nativen Codes für eine einzelne Funktion aktivieren, indem du das Attribut @native hinzufügst:


@native
local function f(x)
return (x + 1)
end
1 In der Zukunft könnten einige Skripte automatisch ausgeführt werden, wenn sie als nützlich festgelegt sind, aber manuell platzierte --!native-Kommentare sind derzeit erforderlich.

Best Practices

Die folgenden Tipps helfen Ihnen, die meisten Nutzen aus der nativen Code-Erzeugung zu ziehen:

  • Es ist am besten, dieses Feature in Skripts zu aktivieren, die eine Menge Berechnungen direkt innerhalb von Luau durchführen. Wenn Sie viel mathematische Operationen auf Tabellen und insbesondere buffer Arten haben, ist das Skript ein guter Kandidat.

  • Nur die Funktionen des Skript, das. PL: die Skriptswerden nativ kompiliert. Der Code in der oberen äußeren Skala wird oft nur einmal ausgeführt und profitiert nicht so sehr wie Funktionen, die mehrmals aufgerufen werden, insbesondere solche, die jedes Frame aufrufen.

  • Es wird empfohlen, die Zeit, die ein Skript oder eine Funktion mit und ohne native Kompilation benötigt, mit dem Skript-Profilierungs-Werkzeug zu messen, um zu beurteilen, wann es am besten verwendet wird. Das Skript-Profilierungs-Werkzeug kann die Leistung von Funktionen messen, um informierte Entscheidungen zu treffen.

  • Es mag bezaubern, den --!native Kommentar in jedem Skript einzufügen, nur um sicherzustellen, dass einige von ihnen schneller ausgeführt werden, aber die native Code-Erzeugung hat einige Nachteile:

    • Die Code-Kompilierungszeit ist erforderlich, was die Startzeit von Servern erhöhen kann.
    • Zusätzliche Speicher ist belegt, um nativ kompilierten Codeszu speichern.
    • Es gibt ein Limit auf die Gesamtmenge der in einem Erlebnis zulässigen nativen Code.

Diese Probleme können durch die kluge Verwendung des Attributs @native behandelt werden.

Code zum Vermeiden

Während alle Funktionen mit oder ohne native Code-Generierung dasselbe Verhalten haben, werden einige von ihnen nicht nativ ausgeführt und können zu einer Deoptimierung oder zu einer Rückgabe zu einer interпреten Ausführung führen. Dies beinhaltet:

  • Verwendung von deprecated getfenv() / setfenv() Aufrufen.
  • Verwendung verschiedener Luau-eingebauter Funktionen wie math.asin() mit nichtzahlbaren Argumenten.
  • Das Überschreiben von unangemessenen Parametern in funktionsübergreifende Funktionen, z. B. das Aufrufen von foo(true) , wenn foo als function foo(arg: string) deklariert ist. Denken Sie immer daran, korrekte 1> Typer-Annotations1> zu verwenden.

Wenn Sie den Skript-Profi verwenden, können Sie die Zeit, die eine reguläre Version der Funktion gegen diejenige, die nativ kompiliert ist, benötigt, vergleichen. Wenn eine Funktion innerhalb eines --!nat

Verwendung von Typ-Anzeigen

Die native Code-Erzeugung versucht, den wahrscheinlichsten Typ für eine bestimmte Variable zu inferieren, um Code-Wege zu optimieren. Zum Beispiel wird angenommen, dass a + b auf Zahlen ausgeführt wird, oder dass eine Tabelle in <

Während die native Code-Erzeugung jeden eingebenunterstützt, können Fehler zu unnötigen Checks führen, was zu einer langsameren Code-Ausführung führt.

Um einige häufige Probleme zu beheben, Luau überprüft Animationen auf Funktion-Argumente, aber es wird dringend empfohlen, Vector3 Funktion-Argumente zu annotieren:


--! native
-- „v“ ist eine tabelle; die funktion ist langsamer aufgrund von tabel检查
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- „v“ wird als Vector3 erklärt; Code für Vector generiert
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
end

Studio-Werkzeuge

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

Debugging

Generell Debugging von Skripten ist unterstützt, aber die Ansichten für Locals/Upvalues können unvollständig und fehlende Variablen aus Call Stack-Frames sein, die nativ ausgeführt werden.

Beachten Sie auch, dass beim Debuggen von Code für die native Kompilation Breakpoints deaktivieren, die nativen Ausführung für diese Funktionen deaktivieren wird.

Skript-Profilierer

In dem Skript-Profi-ler funktionieren Funktionen, die nativ <native> neben ihnen anzeigen:

Example of native functions flagged in the Script Profiler

Wenn eine Funktion markiert @native oder in einem --!nat

Luau-Heap

Im Luau Heap profiler, die von nativen Funktionen aufgenommene Erinnerung wird als [native] Elemente im Diagramm angezeigt.

Example of native memory usage flagged in the Luau Heap profiler

Größen-Analyse

Jedes nativ kompilierte Skript verbraucht Speicher. Wenn die Größe des kompilierten Codes einen vordefinierten Grenze erreicht, stoppt die native Kompilation und der übrige Code wird nicht-nativ ausgeführt. Dies macht es notwendig, Skripte sorgfältig für die native Kompilation auszuwählen.

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

  1. Stellen Sie sicher, dass Sie in Server-Ansicht durch den Client/Server-Switch-Button sind.
  2. Rufen Sie debug.dumpcodesize() von der Command Bar .

In dem Ausgabe-Fenster siehst du die Gesamtzahl der Skripte und Funktionen, die nativ auf der Anrufsstelle kompiliert wurden, die vom Codesverbrauchte den Speicher und die nativen Codegröße begrenzt. Nach dem Zusammenfassungsiehst du eine Tabelle für jedes nativ kompilierte Skript im absteigenden Codegrößenlimit.

Example of native code size displayed in the Output window.

Für jedes Skript, das. PL: die Skriptswird die Ausgabe anzeigen, die Anzahl der kompilierten Funktionen und den nativen Code-Speicherverbrauch. Jede Funktion wird dann in absteigender Reihenfolge der nativen Code-Größe aufgelistet, mit anonymen Funktionen als [anonymous] und gesamten Skripts als [top level] angezeigt. In der finalen Spalte wird der

Beschränkungen und Fehlerbehebung

Die Kompilation von Code in Anweisungen für einen bestimmten CPU erfordert zusätzliche Speicherplätze. Darüber hinaus können Optimierungen für komplexe Funktionen zu lange dauern, um zu ausgeführt zu werden. Ein Treffer auf ein internes Limit berichtet in Studio's Ausgabe-Fenster, einschließlich:

Funktion 'f' in Zeile 20 hat das einzelne Code-Block-Limit überschritten

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

Funktion 'f' in Zeile 20 hat den Funktionscode-Blocklimit überschritten

Dieser Fehler bedeutet, dass eine einzige Funktion mehr als 32K interne Blöcke des Codes enthält. Interne Blöcke des Codes mappen nicht genau auf die Control-Flow-Blöcke in deinem Skript, das. PL: die Skripts, aber dieser Fehler kann vermieden werden, indem die Control-Flow in der Funktion oder in mehrere kleinere Funktionen aufgeteilt wird.

Funktion 'f' in Zeile 200 überschritt das Gesamtmodul-Instruktionslimit

Dieser Fehler bedeutet, dass die Funktion insgesamt ein Limit von 1 Million Anweisungen für das gesamte Skript, das. PL: die Skriptserreicht hat. In einigen Fällen kann die gemeldete Funktion selbst vielleicht eine Menge Anweisungen haben, oder das Limit wurde durch Funktionen früher im Skript erreicht. Um dies

*Funktion 'f' in Zeile 20 ist auf einen internen Abwärtsschaden gestoßen. *(oder) Interner Fehler: Die nativen Code-Generierung ist fehlgeschlagen (Assembly-Abwärtsschaden)

Manchmal enthält eine Funktion komplexe Bits von Code, die der native Code-Kompilator derzeit nicht Ziehpunktkann. Um diesen Fehler zu vermeiden, inspizieren Sie komplexe Ausdrücke im Code und teilen Sie sie auf oder vereinfachen Sie sie, aber betrachten Sie auch die Öffnung eines Fehlerberichts mit einem Beispiel des Codes, der für diesen Grund fehlgeschlagen ist.

Speicherzuweisungslimit für die native Code-Generierung erreicht

Dieser Fehler bedeutet, dass das allgemeine Speicherlimit für nativen Code-Daten erreicht wurde. Um dies zu vermeiden, versuchen Sie, --!native --! native von den mehr메모리intensiven Skripts zu entfernen, so dass kleinere Skripte unter dem Limit platziert werden können. Alternativ verschieben Sie große oder un häufiger aufgerufene Funktionen in ein separates nicht- native Modul.