生成原始代码

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

有了 Luau 对于生成原始代码的支持,您的体验中的服务器端脚本可以直接编译为机器代码指令,而不是通过使用太多重要的 Luau 库或 Roblox API 调用来运行的常规 Bytecode。 此功能可以用于提高服务器上的某些脚本的执行速度,例如使用太多重要的 Luau 库或 Roblox API 调用来运行的脚本。

启用原生

要为 Script 生成本地代码,请在顶部添加 --!native > 评论。


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

这使得脚本中的所有函数都可以生成原始代码,如果认为有价值。不需要进行任何更改;脚本的原始执行行为与之前相同,只是性能不同。所有 Luau 语言和所有 Roblox API 都受到支持。

或者,您可以为一个函数添加 @native 属性,以生成本地代码:


@native
local function f(x)
return (x + 1)
end
1 在未来,一些脚本可能会自动运行,如果确定是否盈利,但手动放置 --!native 评论是当前需要。

最佳实践

以下几个提示将帮助您最大限度地从生成原始代码中获益:

  • 最好在脚本中启用这个功能,这些功能直接在 Luau 内执行计算。如果你有很多数学操作在表上,尤其是 buffer 类型,脚本可能是一个好的候选人。

  • 只有脚本的 函数 才会 natively 编译。顶层 范围 中的代码通常只会执行一次,不会受益于许多次调用,尤其是每个框架中调用的函数。

  • 建议您测量脚本或函数的时间,以便评估它是否最佳使用。脚本分析器 工具可以测量函数的性能,以便做出明智的决定。

  • 有可能诱惑地将 --!native 评论放在 每个 脚本上,以防止一些 из них会更快地执行,但生成 native 代码有一些缺点:

    • 需要编码时间,这可以提高服务器的启动时间。
    • 额外的内存用于存储已编译的验证码。
    • 体验中允许的代码总量有限。

这些问题可以通过灵活使用 @native 属性来解决。

避免的代码

与或无视频代码生成启用时,所有功能都会保持相同的行为,但其中一些功能可能无法正常运行,或可能导致优化或崩溃。这些功能包括:

  • 使用过时的 getfenv() / setfenv() 调用。
  • 使用 math.asin() 使用不能量量的参数。
  • 将不正确的参数类型通过输入函数,例如调用 foofunction foo(arg: string) 被声明为 1> function foo(arg: string)1> 。记得总是使用正确的 4> type annotations4> 。

使用 脚本调试器 时,您可以比较使用默认版本的函数所需的时间与在 --!native 脚本或被标记为 #number 的脚本内的脚本调试器所需的时间。如果 2>number2> 脚本或被标记为 5>number5> 脚本或被标记为 8>number

使用类型注释

生成 native 代码时,它们尝试以最有可能的类型为指定变量演绎,以优化代码路径。例如,它们假设 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 脚本和 #number 函数。

调试

支持脚本的 调试,但局部/升级值的视图可能会是从 调用堆 框架中的未完成或丢失变量。

请注意,在为 native 编译选定代码时,放置 中断点 会禁用该功能的 native 执行。

脚本分析器

脚本分析器 中,函数执行时会显示 <native> 在它们旁边:

Example of native functions flagged in the Script Profiler

如果在 @native#number1 内的函数标记为 #number1 或在 1>#number11> 内的脚本标记为 4>#number14> ,那么该函数可能无法在 7>#number17> 下执行,因为它的交换位置导

Luau 堆

Luau Heap profiler 中,显示的内存由默认函数所占用的内存显示为 [native] 元素在图形中。

Example of native memory usage flagged in the Luau Heap profiler

大小分析

每个 natively 编译的脚本都会消耗内存。 当编译代码的大小达到预定限制时, natives 编译停止,剩余代码运行为非 natives。 这使得它必须选择脚本谨慎为 natives。

要监控个函数和脚本的 native code 大小:

  1. 确保您在 服务器 视图通过 客户端/服务器切换 按钮。
  2. 命令栏 中调用 debu调试.dumpcodesize()。

输出窗口中,您可以看到所有源脚本和函数的总数,它们的内存由其 nativo 代验证码所占用,以及它们的 nativo 代码大小限制。 跟随概括结,您将看到一个表为每个源脚本在代码大小顺序的降序显示。

Example of native code size displayed in the Output window.

对于每个脚本,输出显示功能的数量和内存使用率。每个功能的脚本按语义代码大小的顺序列出,并且显示为 [anonymous] 和整个脚本显示为 [top level]。在最终列中,百分比由相对于源代码大小进行计算。 注意:功能的大小是以

限制和排除问题

将代码编译为特定 CPU 的指令需要额外的存储空间。 此外,对复杂功能的优化可能需要太长时间才能执行。 命中内部限制会报告 Studio 的 输出 窗口中的错误,包括:

在第 20 行中的“f”函数超过了单个代码块指令限制

此错误意味着函数内的一个单独的代码块使用了超过 64K 个指令。这可以通过简化函数或将其分为独立的更小功能来避免。

在线20号时超出功能代码限制

此错误意味着单个函数包含32K个内部代验证码块。内部代码块不会完全地图到控制流程块在您的脚本中,但此错误可通过简化控制流程在函数中或分为个别更小的函数来避免。

在线200超出了模块总指令限制

这个错误意味着,在总体来说,该函数已达到 100 万条指令的上限。 在一些情况下,报告的函数本身可能有很多指令,或限制已被函数早期在脚本中达到。 为了避免此问题,请您移动特别大

*线路 20 的‘f’函数遇到了内部的降低失败 ” *(或) 内部错误:原始代码生成失败 (代码降低)

有时函数包含一个或多个容器式代码,其中的代码可能无法被原始代码编译器处手柄。为了避免此错误,请检查代码中的复杂表达并将其分开或简化,但也请考虑打开一个错误报告,以示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例代码为示例

已达到生成原始代码所需的内存上限

此错误意味着达到了对于 nat 代码数据的整体内存上限。为了避免此,请尝试将 --!native 从更具内存密集的脚本中移除,允许更小的脚本在上限下运行。或者,将大或不常用的函数移到独立的非 nat 模块。