外观
GTA Online 为什么加载那么慢?19.8 亿次 if 循环是怎么回事?
一句话回答:因为两段低效代码——游戏每读一个商店物品都重新数一遍整个 12MB 文件还剩多长,并且每加入一个物品都和之前所有物品逐一查重,63000 个物品累计产生约 19.8 亿次 if 比较。2021 年黑客 t0st 在没有源码的情况下逆向定位并修复,加载时间从 6 分钟缩短到 1 分 50 秒,获 R 星承认并奖励 1 万美元。
两个瓶颈是什么
GTA Online 的商店随活动和 DLC 不断膨胀到 63000 个物品,加载时要解析一份约 12MB 的商品清单,其中有两段烂代码:
1. 反复丈量剩余长度:每读取一个商品,程序都从当前位置数到文件结尾看还剩多少字符,重复 63000 次——就像读一本书时,每翻一页都重新数后面还剩多少页。
2. 平方级查重:每插入一件新物品,都和已插入的所有物品逐一比对确认不重复。放第二个查 1 次,放第三个查 2 次……累加到 62999,一共 0+1+2+…+62999 ≈ 19.8 亿次比较——就像仓库收货员每收一件新货,都拿它和仓库里所有旧货相亲一次,每次都没成。最荒诞的是:这批数据本来就是唯一的,20 亿次比较只为确认一件不可能发生的事。
R 星的程序员是有病吗
其实能理解:代码刚写时商店里可能就几百个商品,低效但快得看不出来。运营几年后内容疯狂膨胀,而运算量是平方级增长。这不是程序员智商问题,而是老系统的典型悲剧:代码没变,世界变了。
黑客是怎么修的
2021 年,黑客 t0st 在没有源代码的情况下,通过采样分析定位出这两个瓶颈并制作了补丁:
- 长度问题:不用每次从头数——文件总长度已知(终点坐标),用终点减当前位置就是剩余长度
- 查重问题:既然每个物品的标识本来就唯一,查重压根没必要,直接跳过
结果:在配置很烂的电脑上,加载时间从 6 分钟缩短到 1 分 50 秒(约 70%),游戏运行一切正常。R 星承认了这个问题,并奖励他 1 万美元。
这个案例为什么经典
- 证明了无源码的黑盒逆向修复是可行的:观察现象 → 采样定位热点 → 反汇编分析 → 打补丁 → 验证
- 是"技术债随规模爆炸"的教科书案例:O(n²) 的算法在 n 小时无感,在 n 大时灾难
- 后来也成为测评 AI 代码分析能力的理想题材(见 AI 能像黑客一样修复屎山代码吗?)
常见误区
- "加载慢是服务器或网络问题" —— 该案例中瓶颈完全在本地 CPU 上的低效解析代码。
- "写出这种代码的程序员很蠢" —— 代码在诞生时是够用的,问题在于没有随数据规模增长而重新审视。
相关条目
作者:人工大黑 · 转写自视频《91分到18分!17个AI横评修代码,能比得过人类黑客吗?》
