Gandi 3.0文档
官网 打开编辑器
文档/调试工作台

诊断规则与日志

录完一段之后,「概览」页最下面那几张卡片给出这次录制的结论:慢在哪、为什么、改哪里。 它们不是通用建议,而是从这一段录制的数字里算出来的,每条都指向具体的角色、脚本或积木。

概览页的结论

一条结论的构成#

每张卡片四部分:

  • 左边的色条是严重程度:红=高,橙=中,蓝=低。排序也按它,高的在上面。
  • 标签(标题前那颗胶囊)是这条的量:有占比的写百分比,有耗时的写毫秒,两样都没有 的写规则名(比如「广播风暴」「线程过多」)。
  • 标题一句话说明是谁、在哪、多严重。
  • 说明是原因和改法。有些卡片下面有「跳到积木」,点了直接切到那个角色、滚到那块积木 并闪一下。

问题较多的作品会同时报出好几条,红橙蓝三色区分轻重:

一次报出七条结论

结论怎么挑出来#

结论是怎么挑出来的

十三条规则各自计算,然后按严重程度排序,同级按每帧毫秒从大到小。指向同一块积木的只留 最靠前的那一条,否则「整体偏慢」和「无等待循环」会把同一段脚本报两遍。最后最多列 8 条。

去重有一个副作用:某条规则明明成立,也可能因为同一段脚本上有排序更靠前的结论而不显示。 要确认就去「线程」和「积木」页看原始数字。

统计范围跟着「帧」页的窗口走。「帧」页上选的是最近 120 / 300 / 900 帧还是「全部」, 概览的结论、线程表、积木表用的都是同一个区间,默认最近 300 帧。只看某一段的结论时, 先在「帧」页把窗口调窄。

如果一条都没算出来,卡片会写「这段跑得很顺」(平均每帧在预算内、超预算的帧不到 5%), 或者「没有找到明显的卡顿源」,并提示去「帧」页找最长的那几帧。

十三条规则#

下面按规则本身列出。页面上的先后取决于严重程度,不是这张表的顺序。

规则 什么时候报
界面开销 帧与帧之间的空档比脚本时间多出 8 ms 以上,而且平均间隔 ≥ 20 ms
无等待循环 / 不刷新屏幕 某段脚本一帧里跑了 200 块以上还停不下来,且每帧 > 0.5 ms。最多 3 条
尖峰 录了 30 帧以上,有超过「中位数×3 且至少 50 ms」的帧,但它们占比不到 20%
最费时的积木 某块占脚本时间 > 8% 且每帧 > 0.3 ms。最多 3 条,「完整」档才有
类别合计 某一类积木合起来 ≥ 30%。最多 2 条,「完整」档才有
自制积木 某个自制积木的定义里,块时间合计 ≥ 25%。最多 2 条,「完整」档才有
广播风暴 一次广播叫醒 > 60 条脚本,或者每帧发 > 4 次。最多 2 条
克隆爆炸 平均每帧新建 ≥ 3 个克隆体
线程过多 同时活着的线程峰值 ≥ 200 条
画笔 每帧画笔操作(落笔、抬笔、图章、设置笔的颜色 / 粗细)≥ 300 次
渲染过重 平均每帧绘制 ≥ 6 ms
角色包揽 作品有 ≥ 4 个角色,其中一个占了 ≥ 70% 的脚本时间,且它有 ≥ 2 段脚本
整体偏慢 平均每帧 > 一帧的预算(30 帧作品是 33.3 ms)

严重程度的划分:

规则 报「高」的线
界面开销 作品之外的开销 > 30 ms
无等待循环 每帧 > 8 ms
不刷新屏幕 峰值 ≥ 400 ms(500 ms 预算已经用尽)
尖峰 最卡那帧 > 200 ms
最费时的积木 占比 > 40%
类别合计 / 自制积木 占比 > 60%
广播风暴 每次叫醒 > 150 条,或每帧 > 20 次
克隆爆炸 每帧 > 20 个,或活着 > 300 个
线程过多 峰值 > 600 条
画笔 每帧 > 2000 次
渲染过重 每帧绘制 > 12 ms
整体偏慢 平均每帧 > 33 ms;不到这条线时它是「低」而不是「中」
角色包揽 永远是「低」

除上面注明的以外,达到触发线但没到「高」的都是「中」。

几条规则的说明#

界面开销是唯一一条不针对作品本身的规则。探针只能测到 VM 里的时间,如果脚本加绘制 只用了几毫秒、帧与帧之间却隔了三十多毫秒,多出来的时间就是被编辑器占掉的:工作区里积木 多、监视器多,或者这个面板自身(「完整」档要给每块积木计时,还要画热度描边)。遇到这条 先切「轻」档再录一段;作品单独运行时没有这部分开销。「界面很卡而面板显示流畅」基本都是 这种情况。

无等待循环的判定是「一帧里同一段脚本跑了 200 块以上」。Scratch 的循环每圈都会让出, 但只要没有积木请求重绘,调度器就会在同一帧里反复回到这条线程,直到用掉这一帧 75% 的预算。 所以真正吃紧的是只有变量和运算、没有动作 / 外观积木的循环。建议加一块「等待 0 秒」,或者 改成「重复执行直到」。

不刷新屏幕是同一条规则的另一半:如果这段脚本运行在勾了「运行时不刷新屏幕」的自制积木 里,结论的措辞会变。一帧执行几万块积木本来就是这种写法的用意,问题在于执行不完。

不刷新屏幕的过程跑不完

「线程」页也会在这段脚本底下标出「不刷新屏幕」:

线程页上的不刷新屏幕标记

类别合计针对的是没有哪一块特别突出、但一整类积木合计占比很高的情况,例如「列表操作」 加起来占了四成。类别有:列表操作、变量、运算、碰撞与距离、侦测、外观、动作、声音、画笔、 自制积木的调用、控制与事件,扩展积木按扩展名单独一类。每类都有对应的建议,比如列表是 「在大列表里『包含』『编号』是逐项查找,能按编号直接取就别查找」。

自制积木。线程记录只把时间算到调用它的那个帽子上,因此看不出自制积木内部占了多少。 这条规则沿着积木的父链走到顶,把顶层是「定义 …」的块单独汇总。

尖峰针对平时正常、隔一阵卡一下的情况,它会报出最卡那一帧里占比最大的是谁。

日志#

「日志」页收集作品运行期间发生的事,比在舞台上用「说」积木打印方便得多。

日志页

一行是:距离面板打开的时间、类别、内容。有些行后面有「跳到积木」。

都记些什么#

类别 什么时候写
事件 点绿旗(「绿旗:作品开始运行」)、全部停止(「所有脚本都停了」)、克隆
说话 角色执行「说」或「思考」时,内容截到 300 字
日志点 断点里填了「日志」的那种,见 断点与单步
变量 「监视」页开了「记录变化」的变量,写成「『关卡』1 → 2」
暂停 命中断点、变量被改、事件断点、手动暂停。单步不记
出错 有脚本编译不了退回逐块解释;断点条件写错或算错
提示 加载了扩展、临时切到解释模式、「不刷新屏幕」失控、载入了录制文件

克隆是合并记录的:同一个来源每两秒结一条,写成「小兵 克隆了 300 个(2 秒内),现在活着 300 个」。持续克隆时只更新这一行,不会一秒刷十条把别的日志冲掉。

「不刷新屏幕」失控那一条尤其值得留意,它说明编辑器已经在限速:

不刷新屏幕失控的提示

自定义积木勾了「运行时不刷新屏幕」又写了跑不完的循环时,解释器每帧会给它 500 毫秒,编辑器 就只剩两三帧每秒。检测到连续跑满预算之后,编辑器会把它压到每帧 40 毫秒,并在这里留一条 提示,写明是哪段脚本。

筛选和搜索#

顶上一排按钮按类别筛:「全部」加上面表里那七类,每个后面带条数。旁边是搜索框(按内容找)、 「跟随」勾选框、「复制」和「清空」。

按类别筛选

「跟随」开着的时候,新日志一到就滚到底;向上翻会自动关掉它,翻回底部又自动接上,正在看的 内容不会被新日志顶走。

「复制」把当前筛出来的内容按 [时间 #帧] 类别: 内容 的格式复制成文本,便于发给别人。

细节#

  • 连续一模一样的行会合并成一条,后面标「×N」。日志点在循环里一帧能打几千条,不合并 无法阅读。
  • 最多留 1000 条,超了从最早的开始丢;界面上一次最多画 400 条。
  • 时间是距离面板打开的秒数,不是作品运行的时间。超过一分钟写成 1:23。
  • 关掉面板日志就清空,需要保留先用「复制」。

相关#