摘要
开战前的“准备页”(确认页)列出英雄、技能、子技能、装备、军队和法术。程序读这页主要靠两件事:在每个固定槽位里用模板匹配认出图标身份,再用 OCR 读数字。项目的目标是 App 预热后每张图 p95 ≤3 秒,而当时热态读一张准备页要约 5 秒。
本实验在严格的预算下做性能诊断:基线和候选各只允许 3 次公开请求(冷 B1、热 B1、热 B2,B1/B2 是两张准备页截图),总共 6 次。分析发现准备页根本不用整图 OCR 模型,却每次都加载它,于是唯一的候选改动是“整图 OCR 模型在第一次真正用到时才加载”。结果:冷请求省了 1.36 秒,所有识别输出严格相等;但热请求仍超过 3 秒,主要耗时在模板匹配。下一步的“同类槽位批量模板计算”只写成了预执行协议,没有运行。
要回答的问题
- 准备页读取的时间花在哪里?
- 能否在不改变任何识别结果(身份、数字、框、分数、拒识)的前提下,找到一处安全的重复工作并去掉?
数据与来源
两张准备页原图,来自同一个保守来源组,独立验收对局数为 0;这是已曝光的开发诊断。参考答案复用之前已审的完整参考:两张图共 155 个“已知”原子项(英雄身份、职业、数字、资源、技能、子技能、装备、军队、法术等),参考只用于事后评分,读取请求不带标签。
方法
- 调用前把图像路径、文件大小/修改时间、参考路径、源码状态和阈值写入冻结 JSON,并先在本地提交执行器。
- 每批启动一个新的常驻进程,依次发冷 B1、热 B1、热 B2 三次请求,用 cProfile(Python 性能剖析器)记录各部分耗时;不预热、不重试、不补读。
- 基线三次请求后选择候选:三次请求整图 OCR 调用都是 0,但启动日志显示加载了整图检测模型、它的识别模型和另一个裁图识别模型——准备页只用裁图识别模型。
- 唯一改动:私有读取器中整图 OCR 改为首次访问时创建、成功后常驻复用;加载失败照常抛出且不缓存。阈值、裁区、读数次数、设备、公开响应都不变。
- 正确性:每对完整响应只排除事先声明的两类耗时字段
seconds,其余做严格类型和值比较,不加浮点容差、不加豁免字段;另用原评分器对 155 项评分。
设置
既有环境和已缓存的 PP-OCRv6 模型,不安装、不下载。测量期间其他会话在并行工作,没有独占 GPU/CPU,所以只能算有限的开发诊断。
结果
| 请求 | 基线 provider 秒 | 候选 provider 秒 | 基线/候选往返秒 |
|---|---|---|---|
| 冷 B1 | 13.0502 | 11.6916 | 13.6955 / 12.2052 |
| 热 B1 | 4.9870 | 4.7473 | 4.9954 / 4.7552 |
| 热 B2 | 4.6368 | 4.4864 | 4.6438 / 4.4925 |
冷请求减少 1.3586 秒(10.41%)。热态路径没有改动图标计算,热请求 0.24/0.15 秒的差异不能归功于候选,可能来自并行负载和计时波动。三对完整响应严格相等;候选日志里不再出现整图检测模型的加载。另一个独立 QA 只读保存证据复核了 796 项检查,全部通过。
识别分母(两张图、155 个已知项): 正确 151、缺失 2、未知 2、错误 0;严格整图全对 0/2。
| 项目 | 正确 / 已知 |
|---|---|
| 英雄身份 | 2/2 |
| 职业 | 0/2(公共格式未暴露,计为缺失) |
| 英雄数字 / 资源 | 14/14 / 12/12 |
| 主技能身份 / 等级 | 11/11 / 11/11 |
| 子技能身份 | 17/17 |
| 装备身份 | 18/18 |
| 军队身份 / 数量 | 14/14 / 14/14 |
| 法术身份 / 显示等级 | 19/20 / 19/20 |
参考中的空位共 77 个,零误填;但其中 48 个是两张图各 24 个背包槽根本没实现,不能把它们当作“正确识别为空”。
剩余耗时: 候选热 B1/B2 中,槽位匹配函数各调用 39 次,累计 3.90/3.86 秒;其中 OpenCV 模板匹配本身 3.46/3.42 秒,调用 19,698/19,554 次。参考图加载约 0.38–0.40 秒。这些时间有嵌套,不能相加。
失败与负结果
- 热态仍超过 3 秒,候选没有解决主瓶颈。
- 独立 QA 第一次运行报了 38 项失败,原因是 QA 自己的字段选择器不支持数组下标,不是产品缺陷;修正后 796 项全部通过,第一次的结果保留。
- 候选执行回执曾短暂记录承载模块为“已删除/未跟踪”,查明是提交工具同步暂存区的瞬态窗口,工作文件未删;原回执保留不改写。
局限
- 每批只有三个带剖析开销的请求,不能给出 p95、稳定加速比或 App 可见等待时间。
- 两张图、一个来源组,不是十场来源隔离验收,也不能宣布准备页 95% 准确率。
结论与下一步
延迟加载整图 OCR 是一处安全的、结果完全不变的冷启动优化,保留。真正的热态瓶颈是约 2 万次模板匹配。已核实现有算法已经按类型和父技能限制了搜索范围,所以“按父技能裁减”“固定槽分类型”不能再当新优化。
下一批预执行协议(未运行): 只做一个候选——把同一类型的多个固定槽位拼成一批(中间留足隔离区),用同一个模板内核一次计算,再只在各槽对应区域取结果;不减少任何身份、参考变体、尺寸(72/80/88/96/104)、偏移、前三候选或读数,也不改 0.75 分/0.08 差值的接受门槛。先用确定性合成矩阵验证完整排名字典与原函数严格相等;只要输出有任何变化就保存反例并停止,不换第二种算法。之后才允许再做一批 6 次真实请求,并且必须看到模板匹配成本或调用量明显下降,才能说有性能价值。
Comments