luau-performance
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseluau-performance
luau-performance
When to Use
适用场景
Use this skill when the task is primarily about Luau runtime cost:
- Profiling code to find real hotspots before changing implementation details.
- Reducing allocation churn, GC pressure, or closure creation in repeated paths.
- Choosing faster table construction, lookup, append, and iteration patterns.
- Making code cooperate with Luau fast paths for builtin calls, method calls, and imports.
- Explaining how compiler and runtime optimizations affect hot functions.
- Tuning a confirmed hot path while balancing readability and maintainability.
- Accounting for sandbox or environment behavior only when it changes Luau execution or deoptimizes code.
Do not use this skill when the task is mainly about:
- Teaching general Luau syntax, control flow, tables, or metatables from first principles.
- Designing deep type-system abstractions, analyzer behavior, or advanced type utilities.
- Roblox-specific replication, streaming, rendering, networking, physics, or other engine performance patterns.
当任务主要涉及Luau运行时代价优化时使用本技能:
- 在修改实现细节前,对代码做性能分析找出真实热点。
- 减少重复执行路径中的分配抖动、GC压力或闭包创建次数。
- 选择更高效的表构造、查询、追加和迭代模式。
- 调整代码以适配Luau针对内置调用、方法调用、导入的快路径机制。
- 解释编译器和运行时优化对热点函数的影响。
- 在平衡可读性与可维护性的前提下调优已确认的热点路径。
- 仅当沙箱或环境行为会改变Luau执行逻辑或导致代码去优化时,才需要考虑这类因素。
当任务主要涉及以下内容时不要使用本技能:
- 从零开始讲解Luau通用语法、控制流、表或元表。
- 设计深度类型系统抽象、分析器行为或高级类型工具。
- Roblox专属的复制、流加载、渲染、网络、物理引擎或其他引擎性能模式。
Decision Rules
决策规则
- Start with measurement. If the code is non-trivial, profile or benchmark before making optimization claims.
- Fix algorithmic cost before micro-optimizing bytecode-level details.
- Prioritize changes that remove repeated work, repeated allocation, or repeated dynamic dispatch in hot paths.
- Keep performance-sensitive modules in a pure environment. Avoid ,
getfenv, andsetfenvwhere speed matters.loadstring - Prefer stable table shapes, direct field access, direct builtin calls, and simple call graphs in hot code.
- Use environment-specific compilation features only after measurement shows a likely win and the runtime actually supports them.
- If the task shifts into core language teaching, use .
luau-core - If the task shifts into types, inference, or annotations as the main subject, use .
luau-types - If the task depends on Roblox engine architecture instead of Luau execution behavior, hand off to the appropriate skill.
roblox/* - If a request mixes performance work with out-of-scope topics, answer only the Luau runtime portion and exclude the rest.
- 优先做性能测算。如果代码逻辑较复杂,在提出优化结论前先做性能分析或基准测试。
- 在做字节码层面的微优化前,先修复算法层面的性能开销问题。
- 优先处理能减少热点路径中重复执行、重复分配或重复动态调度的改动。
- 对性能敏感的模块要保持在纯净环境中运行。在追求速度的场景下避免使用、
getfenv和setfenv。loadstring - 热点代码中优先使用稳定的表结构、直接字段访问、直接内置函数调用和简单调用图。
- 仅当测算结果证明能带来明显收益且运行时确实支持时,再使用环境专属的编译特性。
- 如果任务转向核心语言教学,使用。
luau-core - 如果任务的核心主题转向类型、类型推导或注解,使用。
luau-types - 如果任务依赖Roblox引擎架构而非Luau执行行为,转交给对应的技能处理。
roblox/* - 如果请求混合了性能工作和范围外的主题,仅回答Luau运行时相关的部分,其余内容排除。
Instructions
使用指南
- Define the workload first:
- what runs often,
- what allocates often,
- what is on the critical path,
- what metric matters most: wall time, frame budget, or memory churn.
- Profile before rewriting. Use sampling or environment tooling to identify functions that actually dominate runtime.
- Optimize the largest validated bottleneck first. Do not spread micro-optimizations across cold code.
- Reduce allocation pressure in repeated paths:
- avoid rebuilding tables every iteration,
- avoid creating fresh closures in loops unless necessary,
- avoid retaining tables or connections longer than needed.
- Shape tables for the runtime:
- use literals to create object-like tables with all known fields up front,
- keep object layouts uniform across calls,
- use only for array-like tables with known capacity.
table.create
- Choose iteration deliberately:
- use generalized iteration for normal table traversal,
for k, v in t do - use only when stop-at-first-
ipairsbehavior is required,nil - use numeric loops when the index itself is needed or sequential writes are part of the algorithm.
- use generalized iteration
- Keep builtin fast paths obvious:
- call builtins directly, such as or
math.max(x, y),string.byte(s, 1) - do not hide hot builtin calls behind unnecessary indirection,
- prefer builtin function form over method form when fastcall behavior depends on it.
- call builtins directly, such as
- Keep call sites compiler-friendly:
- prefer for hot helpers,
local function - avoid unnecessary mutation of captured values,
- keep small helpers local to the module when that improves inlining opportunities.
- prefer
- Keep metatable usage cheap in hot code:
- store data on the object itself,
- point directly at a table,
__index - avoid functions and deep lookup chains on critical paths.
__index
- Treat environment features as performance constraints:
- ,
getfenv, andsetfenvcan deoptimize imports and fast builtin handling,loadstring - debugging and breakpoints can alter observed runtime behavior in some environments,
- native compilation, where supported, should be applied selectively and measured.
- Preserve practicality. Prefer the simplest change that removes measurable cost, even if a more aggressive rewrite is theoretically faster.
- 先明确工作负载特征:
- 哪些逻辑会频繁运行,
- 哪些逻辑会频繁分配内存,
- 哪些逻辑处于关键路径上,
- 核心关注的指标是什么:运行耗时、帧预算,还是内存抖动。
- 重写代码前先做性能分析。使用采样分析或环境自带工具定位真正占主导运行时间的函数。
- 优先优化已验证的最大瓶颈。不要在冷代码上分散做微优化。
- 降低重复路径中的分配压力:
- 避免每次迭代都重新构造表,
- 除非必要,不要在循环中创建新闭包,
- 避免过长时间持有不需要的表或连接。
- 为运行时优化设计表结构:
- 使用字面量创建对象型表,提前声明所有已知字段,
- 保持不同调用间的对象布局一致,
- 仅对已知容量的数组型表使用。
table.create
- 按需选择迭代方式:
- 普通表遍历使用通用迭代,
for k, v in t do - 仅当需要遇到第一个就停止的行为时使用
nil,ipairs - 当需要索引本身或算法包含顺序写入操作时使用数值循环。
- 普通表遍历使用通用迭代
- 保证内置函数快路径可被识别:
- 直接调用内置函数,例如或
math.max(x, y),string.byte(s, 1) - 不要在热点路径中通过不必要的间接层调用内置函数,
- 当快调用行为依赖函数形式时,优先使用内置函数形式而非方法形式。
- 直接调用内置函数,例如
- 保持调用点对编译器友好:
- 热点辅助函数优先使用定义,
local function - 避免不必要的捕获值修改,
- 小型辅助函数定义在模块局部,提升内联概率。
- 热点辅助函数优先使用
- 热点代码中控制元表使用成本:
- 数据直接存储在对象本身,
- 直接指向一张表,
__index - 关键路径上避免使用函数和深层查找链。
__index
- 将环境特性视为性能约束:
- 、
getfenv和setfenv会导致导入和内置函数快路径处理去优化,loadstring - 调试和断点会改变部分环境下的运行时行为观测结果,
- 原生编译(若支持)应选择性使用并做性能测算。
- 保持方案实用性。优先选择能消除可观测开销的最简单改动,即便理论上更激进的重写速度更快。
Using References
参考文档
- Open for the main Luau fast-path model: table access, imports, method calls, iteration, and allocation-aware table construction.
references/luau-performance-guide.md - Open for profiler workflow, interpreting flame graphs, naming functions for attribution, and environment-specific profiling notes.
references/profiling-guide.md - Open for compiler limits, inlining, constant folding, upvalues, closure caching, and selective native compilation guidance.
references/runtime-and-compiler-optimization-notes.md - Open for practical choices around
references/library-performance-sensitive-patterns.md,math,string, iteration helpers, and array-oriented APIs.table - Open for the environment rules that disable or weaken runtime optimizations.
references/sandbox-constraints-relevant-to-runtime-behavior.md - Do not open other skill references unless the task clearly crosses into another skill's scope.
- 打开查看Luau快路径核心模型:表访问、导入、方法调用、迭代、感知分配的表构造。
references/luau-performance-guide.md - 打开查看性能分析工作流、火焰图解读、归因用函数命名规范、环境专属性能分析注意事项。
references/profiling-guide.md - 打开查看编译器限制、内联、常量折叠、上值、闭包缓存、选择性原生编译指导。
references/runtime-and-compiler-optimization-notes.md - 打开查看
references/library-performance-sensitive-patterns.md、math、string、迭代辅助工具、数组导向API的实用选择建议。table - 打开查看会禁用或削弱运行时优化的环境规则。
references/sandbox-constraints-relevant-to-runtime-behavior.md - 除非任务明确跨到其他技能范围,否则不要打开其他技能的参考文档。
Checklist
检查清单
- A measurement plan or profiler result exists for the claimed hotspot.
- The proposed change targets a path that runs often enough to matter.
- Algorithmic cost has been considered before micro-tuning syntax.
- Allocation churn is reduced where the code repeats.
- Table shape and iteration strategy match the data pattern.
- Builtin calls stay direct enough to preserve fast paths where possible.
- Environment deoptimizers such as ,
getfenv, orsetfenvare avoided in hot modules.loadstring - Any environment-specific compilation feature is justified by measurement, not guesswork.
- The guidance stays within Luau execution behavior and avoids Roblox engine performance topics.
- 声称的热点有对应的测算计划或性能分析结果支撑。
- 提议的改动针对的是运行频率足够高、影响足够大的路径。
- 做语法微优化前已经考虑了算法层面的开销问题。
- 重复执行的代码中分配抖动已被降低。
- 表结构和迭代策略匹配数据模式。
- 尽可能保持内置函数调用直接,保留快路径。
- 热点模块中避免了、
getfenv、setfenv等会导致去优化的环境特性。loadstring - 所有环境专属编译特性都有测算结果支撑,而非主观猜测。
- 指导内容仅涉及Luau执行行为,不涉及Roblox引擎性能相关主题。
Common Mistakes
常见错误
- Optimizing unmeasured code because it "looks hot."
- Using for dictionaries instead of arrays.
table.create - Assuming or
pairsare automatically faster than generalized iteration.ipairs - Rewriting into cached method locals even when Luau already optimizes method calls well.
obj:Method() - Hiding builtin calls behind wrappers or indirect dispatch on a hot path.
- Varying object table keys heavily and then expecting field lookup caching to stay effective.
- Using only for reads and assuming it has no optimization cost.
getfenv - Sprinkling native compilation directives everywhere without measuring memory, startup, or actual runtime wins.
- 仅凭“看起来是热点”就优化没有经过测算的代码。
- 对字典而非数组使用。
table.create - 认为或
pairs天然比通用迭代更快。ipairs - 即便Luau已经对方法调用做了很好的优化,还是把重写为缓存的方法局部变量。
obj:Method() - 在热点路径中通过包装器或间接调度隐藏内置函数调用。
- 对象表的键变化非常频繁,却期望字段查找缓存保持高效。
- 仅为了读操作使用,认为它没有优化成本。
getfenv - 不加测算就到处添加原生编译指令,没有考虑内存、启动耗时或实际运行时收益。
Examples
示例
Preallocate and fill arrays sequentially
预分配数组并顺序填充
luau
local function buildSquares(count)
local result = table.create(count)
for i = 1, count do
result[i] = i * i
end
return result
endluau
local function buildSquares(count)
local result = table.create(count)
for i = 1, count do
result[i] = i * i
end
return result
endKeep builtins direct in hot code
热点代码中保持内置函数直接调用
luau
local function clamp01(x)
return math.min(math.max(x, 0), 1)
endluau
local function clamp01(x)
return math.min(math.max(x, 0), 1)
endUse stable object layouts and direct __index
__index使用稳定对象布局和直接__index
__indexluau
local Counter = {}
Counter.__index = Counter
function Counter.new(step)
return setmetatable({
value = 0,
step = step,
}, Counter)
end
function Counter:advance()
self.value += self.step
return self.value
endluau
local Counter = {}
Counter.__index = Counter
function Counter.new(step)
return setmetatable({
value = 0,
step = step,
}, Counter)
end
function Counter:advance()
self.value += self.step
return self.value
endAvoid deoptimizing the environment in performance-sensitive modules
性能敏感模块中避免环境去优化
luau
local function magnitude2(x, y)
return math.sqrt(x * x + y * y)
end
return magnitude2luau
local function magnitude2(x, y)
return math.sqrt(x * x + y * y)
end
return magnitude2