脚本调试器 是 开发者控制台 中的工具,可让您记录所有运行的脚本的调试会话并查看其 CPU 时间成本,以自定义的记录和显示设置。它可以记录所有类型的函数调用,包括 Luau 函数、方法调用和属性访问。该工具有助于识别占用最多 CPU 资源并降低性能的脚本。
记录调试会话
在录制之前,您需要从以下环境中选择录制环境:
您还可以设置以下录制选项:
行为 | 选项 | 默认 | 描述 |
---|---|---|---|
频率 | 每秒 1000 次(1 KHz)10,000 次(10 KHz) | 1 KHz | 10 KHz 频率的精度更高,因为脚本调试器可能不会捕捉到比选定频率更频繁地执行的 API 调用,但它也有更高的性能成本。 |
会话长度 | 1分钟5分钟10分钟手册 | 手动 | 手动选项需要您手动停止录制。 |
实时投票行为 | 开启关闭 | 关 | 在调试会话期间,每秒钟都会调查和刷新调试数据。 |
要记录新的调试会话:
打开开发者控制台。
扩展工具下拉列表以选择 脚本调试器 。
扩展客户端-服务器下拉列表以选择 客户端 或 服务器 。
(可选)检查 实时 复选框以启用实时投票行为。
(可选)选择 频率 和 时间 以选择记录频率和会话时长,如果你不想使用默认值。
单击 开始 以开始调试会话。如果你设置了一个时间长度,脚本调试器会显示一个倒计时计时器,其中包含会话中剩余时间。
单击 停止 或等待录制完成以显示调试数据。
阅读调度数据
在会话停止后,脚本调试器生成一个表,显示每个函数调用的 CPU 时间消耗量。表排序函数从最多花费时间到最少花费时间,允许您按名称搜索特定函数。它提供以下两个视图:
- 调用图 (默认): 根据框架任务将函数调用分类并显示为树状结构。该视图将每个任务类别显示为同一个根下的节点,并允许您扩展它们以查看函数。您还可以将鼠标悬停在树中的任何节点上,查看文件和行信息。例如, 步进/相机输入/<anonymous> 可能会显示 Players.[LocalPlayer].PlayerScripts.PlayerModule.CameraModule.CameraInput:125 。
- 功能 :列出所有功能,不分类地列出它们的任务。
您还可以从以下显示选项中选择,以满足调试需求:
名称 | 选项 | 默认 | 描述 |
---|---|---|---|
单位 | 毫秒 (ms)百分比 (%) | ms | 显示每次 API 调用所花费的时间以毫秒或总记录会话百分比的形式。 |
平均 | 关1-秒1-分钟5-分钟10-分钟 | 关 | 计算选定值在每次API调用上的平均时间。如果您选择超过会话长度的选项,脚本调试器会将会话长度扩展到计算平均值。例如,您可以选择 5 分钟选项来查看 1 分钟会话的预期平均值,如果您运行代码 5 分钟。 |
导出调试数据
脚本调试器允许您将记录的调试数据导出为 JSON 文件。要在调试会话后导出记录的数据:
在脚本调试器窗口上,单击 导出 。
在输出窗口中,选择要输出的调试会话。如果你想设置自定义名称,请重命名默认文件名称。
单击 导出 以保存 JSON 文件。
导出的 JSON 文件包括以下字段:
- 版本 : 版本号。
- SessionStartTime :以毫秒为单位的时戳,记录了会话开始时间。
- 会话结束时间 :以毫秒为单位的时戳,记录会话结束时间。
- 类别 : 在调试会话中记录的框架任务类别阵列。每个入口包括:
- 名称 :每个框架任务类别的名称。
- 节点ID :任务类别(节点)的唯一标识符。它是 1 基于索引到 Nodes 数组列。例如,你可以通过检索 Nodes 中的第 123 个元素来查找带有 NodeId 的节点 123 。
- 节点 : 在调试会话中记录的节点阵列。每个入口包括:
- 总持续时间 :节点在微秒内花费的 CPU 时间量。
- 功能ID :一个阵列的函数独特标识符。
- 节点ID : 一个阵列的节点ID。
- 功能 : 一个记录在调试会话中的函数阵列。
- 总持续时间 :函数在微秒内花费的 CPU 时间量。
- 名称 :如果可用,函数名称。
- 来源 :如果可用的话,函数的来源。
- 行 :如果可用,函数的行号。
- 旗帜 :指示任何特定函数执行环境的一小块字段。目前可以有以下值:
- 0 : 第 0 位代表在原生代码生成下执行的 IsNative 。
- : 第 1 位表示为插件的一部分进行执行。
例如输出的分析数据
{
"Version":2,
"SessionStartTime":1704850750514,
"SessionEndTime":1704850751198,
"Categories":
[
{"Name":"Parallel Luau","NodeId":4},
{"Name":"Heartbeat","NodeId":1}
],
"Nodes":
[
{"TotalDuration":2530,"FunctionIds":[1],"NodeIds":[2]},
{"TotalDuration":2530,"FunctionIds":[2,5],"NodeIds":[3,7]},
{"TotalDuration":1267},
{"TotalDuration":7746,"FunctionIds":[3],"NodeIds":[5]},
{"TotalDuration":7746,"FunctionIds":[4],"NodeIds":[6]},
{"TotalDuration":7746},
{"TotalDuration":1263,"FunctionIds":[6],"NodeIds":[8]},
{"TotalDuration":1263,"FunctionIds":[7],"NodeIds":[9]},
{"TotalDuration":1263,"FunctionIds":[8],"NodeIds":[10]},
{"TotalDuration":1263}
],
"Functions":
[
{"Name":"main","TotalDuration":2530},
{"Source":"builtin_ManageCollaborators.rbxm.ManageCollaborators.Packages._Index.roblox_rodux-3.0.0.rodux.Store","Line":81,"TotalDuration":1267},
{"Name":"Script","TotalDuration":7746},
{"Source":"Workspace.Actor.Script","Line":1,"TotalDuration":7746},
{"Source":"builtin_DeveloperInspector.rbxm.DeveloperInspector.Packages._Index.DeveloperFramework.DeveloperFramework.UI.Components.Grid","Line":221,"TotalDuration":1263},
{"Source":"builtin_DeveloperInspector.rbxm.DeveloperInspector.Packages._Index.DeveloperFramework.DeveloperFramework.UI.Components.Grid","Name":"_update","Line":236,"TotalDuration":1263},
{"Source":"builtin_DeveloperInspector.rbxm.DeveloperInspector.Packages._Index.DeveloperFramework.DeveloperFramework.UI.Components.Grid","Name":"_getRange","Line":277,"TotalDuration":1263},
{"Source":"[C]","Name":"ScrollingFrame.CanvasPosition","TotalDuration":1263}
]
}