Za pomocą wsparcia dla kodu bazowego można natychmiastowo kompilować kody serwera w twoim doświadczeniu, zamiast wszystkich zwykłych instrukcji bajtowych, które wykonuje procesor, co jest znacznie szybsze niż normalny bajtowy kod maszyny, w szczególności tych, które mają wiele liczbowych obliczeń bez używania zbyt wiele ciężkich instrukcji bajtowych lub wewnętrznych
Włączanie natywne
Aby włączyć generację kodu dla Script, dodaj komentarz --!native na górze:¹
--!pozostałyprint("Hello from native code!")
To umożliwia generację kodu dla wszystkich funkcji w skrypcie i zakres poziomu, jeśli uznano go za opłacalny. Nie są wymagane dodatkowe zmiany; zachowanie zachowania kodu jest dokładnie takie samo jak przedtem i tylko wydajność jest inna. Wszystkie funkcje języka Luau i wszystkie API Roblox pozostają wspierane.
Alternatywnie możesz włączyć generację kodu dla poszczególnej funkcji, dodając atrybut @native :
@native
local function f(x)
return (x + 1)
end
Najlepsze praktyki
Poniższe wskazówki pomogą Ci najbardziej skorzystać z generacji kodu natywnego:
Najlepiej włącz tę funkcję w skryptach, które wykonują wiele obliczeń bezpośrednio w Luau. Jeśli masz wiele operacji matematycznych na tabelach i szczególnie buffer typach, skrypt może być dobrym kandydatem.
Tylko funkcje skryptu są kompilowane natywnie. Kod w górnym zewnętrznym scope jest często wykoniwany tylko raz i nie korzysta z tyle dużo, jak funkcje, które są nazywane wiele razy, szczególnie te, które są nazywane za każdym razem.
Zaleca się, aby zmierzyć czas trwania skryptu lub funkcji z włączoną lub bez włączoną kompilacją natywną, aby ocenić, kiedy jest najlepiej go użyć. Narzędzie Skrypt Profiler może zmierzyć wydajność funkcji, aby podjąć informowane decyzje.
Może być tentujące, aby umieścić komentarz --!native w każdym każdym skrypcie tylko w przypadku, że niektóre z nich będą się wykonują szybciej, ale generacja kodu natywnego ma kilka wad:
- Czas kompilacji kodu jest wymagany, co może zwiększyć czas uruchomienia serwerów.
- Dodatkową pamięć zajmuje się przechowywanie kodu kompilowanego natywnie.
- Istnieje limit na całkowitą ilość pozwoloną kodu w wersji doświadczenia.
Te problemy można naprawić poprzez doskonałe użycie atrybutu @native.
Kod do uniknięcia
Podczas gdy wszystkie funkcje zachowują się tego samego z prawdopodobnie włączoną generacją kodu natywnego lub bez niego, niektóre z nich nie będą działać natywnie i mogą powodować dezoptymalizację lub spadkę wykonania. Te obejmują:
- Używanie różnych zbudowanych funkcji Luau, takich jak math.asin() z nieliczbymi argumentami.
- Przekazywanie niepoprawnie napisanych parametrów do funkcji typu, na przykład wzywanie foo(true) , gdy foo jest zadeklarowany jako function foo(arg: string) . Pamiętaj, aby zawsze używać poprawnych 1> anotacji typu1> .
Gdy używasz profilera skryptów, możesz porównać czas potrzebny na uruchomienie funkcji przez wersję regularną funkcji w porównaniu z tą, która jest kompilowana natywnie. Jeśli funkcja wewnątrz --!native lub oznaczona @native nie wydaje się być uruchomiona w trybie natywnym, jeden lub więcej cz
Używanie właściwości anotacji
Geneneracja kodu natywnego próbuje zidentyfikować najbardziej prawdopodobny typ dla danej zmiennej w celu optymalizacji ścieżek kodu. Na przykład, założono, że a + b
Podczas gdy generacja kodu natywnego będzie wspierała dowolny wpisywać, błędy mogą wywołać niepotrzebne czynności, co powoduje powolniejsze wykonanie kodu.
Aby rozwiązać kilka problemów, Luau weryfikuje anotacje na argumentach funkcji, ale szczególnie zaleca się anotować Vector3 argumenty:
--!pozostały
-- „v” jest domyślnie funkcją stosującą się do tabeli; funkcja działa powoli z powodu sprawdzeń tabeli
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- „v” jest deklarowany jako Vector3; kod specjalny dla wektorów jest generowany
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
end
Narzędzia Studio
Następujące narzędzia Studio są wspierane dla --!native skryptów i funkcji #number1.
Debugowanie
Dla debugowania skryptów jest wspierane, ale widoki dla lokalnych/upvalues mogą być niekompletne i brakujące zmienne z Call Stack ram, które są uruchomione natywnie.
Uwaga: przy debugowaniu kodu wybranego dla kompilacji natywnej, umieszczenie breakpointów spowoduje wyłączenie natywnej egzekwucji dla tych funkcji.
Profilaktyk Skryptów
W Skrypt Profiler funkcje wykonujące <native> obok nich:
Jeśli funkcja oznaczona @native lub w środku --!native skryptu nie pokazuje annotacji <native>, że funkcja nie jest uruchomiona w trybie natywnym z powodu 2> punktu przerwy2> lub umieszczenia, użycia 5>kod
Luau
W profilu Luau Heap pamięć wzięta przez funkcje natywne wyświetla się jako [native] elementy w grafice.
Analiza rozmiarów
Każdy w pełni zkompilowany skrypt konsumuje pamięć. Gdy rozmiar zkompilowanego kodu osiąga wstępnie zdefiniowaną granicę, zatrzymanie kompilacji natywnej i wykonanie pozostałego kodu nie jest możliwe. To czyni niezbędnym wybieranie skryptów w sposób ostrożny dla kompilacji natywnej.
Aby monitorować rozmiar kodu źródłowego poszczególnych funkcji i skryptów:
- Upewnij się, że jesteś w widoku serwera poprzez przycisk przełącznik klient/serwer.
- Przywołaj debug.dumpcodesize() z Barwy Komendy .
W oknie Wyjście zobaczysz ogólną liczbę skryptów i funkcji, które zostały natywnie kompilowane do momentu wezwania, pamięci konsumowanej przez ich kod źródłowy i limitu rozmiaru kodu. Po podsumowaniu zobaczysz tabelę dla każdego skryptu z kodu źródłowego w porządku kodu.
Dla każdego skryptu wyświetlany jest liczba funkcji kompilowanych i konsumpcja pamięci kodu źródłowego. Każda funkcja jest następnie wymieniona w rosnąco małym rozmiarze kodu źródłowego, z anonimowymi funkcjami pokazanymi jako [anonymous] i całe skrypty pokaz
Ograniczenia i Rozwiązywanie Problemów
Komparowanie kodu w instrukcje dla określonego CPU wymaga dodatkowej pamięci. Ponadto optymalizacje dla złożonych funkcji mogą zająć zbyt wiele czasu do wykonania. Uderzenie wewnętrznego limitu spowoduje raport błędu w oknie Wyjście Studio, w tym:
Funkcja 'f' w linii 20 przekroczyła limit jednego kodu bloku
Ten błąd oznacza, że jeden blok kodu w funkcji użył ponad 64K instrukcji. Można to uniknąć poprzez uproszczenie funkcji lub podzielenie jej na pojedyncze mniejsze funkcje.
Funkcja 'f' w linii 20 przekroczyła limit kodu funkcjonalnego
Ten błąd oznacza, że jedna funkcja zawiera więcej niż 32K wewnętrznych bloków kodu. Wewnętrzne bloki kodu nie mapują dokładnie bloków kontrolnych w twoim skrypcie, ale ten błąd można uniknąć, poprzez uproszczenie kontrolowania w funkcji lub podzielenie go na pojedyncze mniejsze funkcje.
Funkcja 'f' w linii 200 przekroczyła limit ogólnego instrukta modułu
Ten błąd oznacza, że w sumie funkcja osiągnęła limit 1 miliona instrukcji dla całego skryptu. W niektórych przypadkach raportowana funkcja sama może mieć wiele instrukcji lub limit może zostać osiągnięty przez funkcje wcześ
*Funkcja 'f' w linii 20 spotkała się z wewnętrznym spadkiem funkcji *(lub) Wewnętrzny błąd: Prawy generowanie kodu natywnego (topnięcie z montażu)
Czasami funkcja zawiera skomplikowane bity kodu, które kompilator kodu natywnego nie może obecnie obsługiwać. Aby uniknąć tego błędu, zbadaj skomplikowane wyrażenia w kodzie i podziel je lub uproszcz je, ale rozważ również otwarcie raportu błędu z przykładem kodu, który nie działał z tego powodu.
Osiągnięto limit przypisu pamięci dla kodu generowanego dla natywnej kodu
Ten błąd oznacza, że ogólny limit pamięci dla danych kodu natywnego został osiągnięty. Aby to uniknąć, spróbuj usunąć --!native > z bardziej wymagających skryptów, pozwalając na umieszczenie większych lub rzadziej nazywanych funkcji w oddzielnym modułem niezależnym od pamięci. Alternatywnie przenieś duże lub rzadziej naz