生成原始代碼

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

有了 Luau 對本地代碼生成的支持,您的體驗中的服務器端指令碼可以直接編譯為機器代碼指令碼,而不是使用 Luau 執行器上的常見字碼。這個功能可以用來提高某些服務器伺服器上的指令碼執行速度,例如使用不使用太多重要的 Luau 庫或 Roblox API 呼叫。

啟用原住民

要啟用 Script 的原始碼生成,請在上方的 --!native 中添加 1>--!native1> 元素。


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

這使用 Luau 語言的原生代碼生成所有功能的腳指令碼,並且最高層級的範圍,如果認為有價值。不需要進行任何額外的變更;執行原生碼的腳本正確相同,只是性能不同。所有 Luau 語言和所有 Roblox API 的所有功能都支持。

您也可以為個別函數啟用原始碼生成機制,並且新增 @native 屬性:


@native
local function f(x)
return (x + 1)
end
1 在未來,有一些指定為「有效」的指令碼可能會自動執行,但需要手動放置 --!native 評論。

最佳實踐

下列提示將幫助您從原始代碼生成中獲得最大好處:

  • 最好將此功能集中在執行大量計算的脚本中。如果你有大量的數學操作在表和特히 buffer 類型上,這可能是個好候選人。

  • 只有 指定的指令碼數 會在內部自動軯載。上方的 範圍 中的代碼通常只會執行一次,並且不會像多次呼叫的函數那麼有益。

  • 建議您測量指定程式碼或函數的時間,以便確認在使用它時是否最適當。程式碼分析工具 可以測量程式碼以作出明智的決定。

  • 可能會誘惑地放置 --!native 留言在 每 個 script 中,以防有些會執行更快,但原始代碼生成有一些缺點:

    • 需要代碼編譯時間,這可以增加服務器的啟動時間。
    • 額外的記憶體被佔用來儲存原始碼。
    • 體驗中允許的原始碼數量有限。

這些問題可以通過對 @native 屬性的合理使用來解決。

代碼以避免

雖然所有功能都會以啟用或無啟用原生代碼生成器的方式相同,但有些功能可能無法在原生模式下執行,或可能會導致斷損或錯誤解釋。這些功能包括:

  • 使用過時的 getfenv() / setfenv() 呼叫。
  • 使用 math.asin() 與非數值參數的各種內置功能。
  • 將不正確的參數傳送到輸入功能,例如 呼叫 ooo(true) 當 ooo 宣佈為 2>function foo(arg: string)2> 時。記得使用正確的 5> type annotations5> 。

使用 腳本檢查器 時,您可以比較正常版本的函數所需的時間與在 --!native 內部或標有 #number 的腳本或標記。如果 2> 腳本檢查器內的腳本或標記有 5> 來自5> 列表上的一個或多個因

使用 Type 標籤

為了優化代碼路徑,對於指定變量的代碼生成時,會嘗試判斷其最有可能的類型。例如,假如 a + b 在數量上執行,或是在 t.X

雖然 native 代碼生成會支持任何輸入,但錯誤預測可能會啟動不必要的檢查,導致更慢的代碼執行。

為了解決一些常見問題,Luau會在功能參數上標記,但建議您特別地標記 Vector3 參數:


--!原生
-- 「v」是指表;表驗證會因表檢查而執行更慢的功能
local function sumComponentsSlow(v)
return v.X + v.Y + v.Z
end
-- 「v」是宣告成為Vector3;代碼專為向量生成
local function sumComponentsFast(v: Vector3)
return v.X + v.Y + v.Z
end

工作室工具

下列 Studio 工具支援 --!native 和 0> number10> 指令碼,以及 3> 6>number16> 函數。

調試

支援 調試 指令碼,但 調試 可能會在本地/上價值之視圖中存在不完整或遺失變量。

您還需要注意,當為原始碼選擇了「零件」時,放置斷點會使原始碼無法執行此功能。

腳本分析器

Script Profiler 中,執行 <native> 的函數靠近他們:

Example of native functions flagged in the Script Profiler

如果 @native#number1 內的函數標記為 #number1 或 1>#number11> 內的 script 不會顯示 4> --!nat

Luau 堆

Luau Heap profiler 中,記錄原始功能所使用的記憶體顯示為 [native] 元素在圖形中。

Example of native memory usage flagged in the Luau Heap profiler

大小分析

任何需要 natively 編譯的指令碼都需要使用記憶體。當編譯代碼的大小達到預設限制時,記憶體編譯將停止,剩餘代碼將運行非 natively。這使得必須選擇 natively 編譯的指令碼。

要監視個別功能和指令碼的原始代碼尺寸:

  1. 確認您在 伺服器 視窗通過 客戶/伺服器切換 按鈕。
  2. 指令條 中召喚 debu偵錯.dumpcodesize()。

輸出 視窗中,您可以看到所有已經在內部以原始碼寫入點的時候已經 natively 編譯完成的指令碼和函數的總數,以及記錄在內部代碼中的記憶體使用率和代碼大小上限。在總簡介中,您會看到一個表表示每個內部寫入的指令碼的大小。

Example of native code size displayed in the Output window.

對於每個指令碼,輸出會顯示已編譯的功數數量和原始碼內存使用率。每個功數都會以不同的順序顯示在原始碼大小的減少中,並且以匿名功數顯示為 [anonymous] 和整個指令碼顯示為 [top level]。在最後一個柱位中,將

限制和排解

將代碼譯化為特定 CPU 的指令需要額外的存儲空間。此外,對複雜功能的優化可能需要太長時間才能執行。擊中內部限制會導致 Studio 的 輸出 窗口發生錯誤,包括:

功能 'f' 在第 20 行超出單一代碼區塊指令限制

此錯誤表示單個功能區內的代碼使用了超過 64K 個指令。這可以通過簡化功能區或將其分為個別更小的功能來避免。

第 20 行中的「f」函數超出功能代碼限制

此錯誤表示單個功能包含超過 32K 個內部代碼的內部方塊。 內部方塊的代碼不完全地映射到控制流程塊中,但此錯誤可以通過減少控制流程塊中的方塊來避免。

穿線 200 的「f」功能超出總模組指令限制

此錯誤表示,總共,功能已達到 1 百萬個指令的全部指令上限。 在一些情況下,報告的功能本身可能有很多指令,或限制可能已被功能早在 script 中。 為了避免此問題,建議

在第 20 行遇到了「f」函數內部降低失敗 (或) 內部錯誤:原始代碼生成失敗 (Assembly 降低)

有時候功能包含來自原始代碼編譯器無法處手把的複雜代碼。為了避免此錯誤,請在代碼中檢查複雜的表達式,並將它們分開或簡化,但也考慮開啟一個錯誤報告,以示範代碼發生此錯誤的原因。

已達到遊戲源碼生成的內存限制

此錯誤表示原始碼資料的總記憶限已達到。若要避免此情況,請嘗試從更具記憶量的指令碼中移除 --!native ,以允許更小的指令碼容量。或者將大型或不頻繁呼叫的函數移到獨立的非頻繁模組。