大概就是,一个if循环19.8亿次,而且7年没人敢动....

真事,就出现在知名游戏大厂R星的知名大作 GTA 5 中。

而且,19.8亿次的if循环,今天仍然在世界各地的玩家cpu上跑着。

3月16日,R星终于官宣准备修复了!

主动改善玩家游戏体验?不存在的。

要主动,哪里还要等七年?

这篇揭R星老底的帖子在全网大火后,R星不得不出面应对。

在和黑客大哥联系后,R星认可了他的改进方法,宣布在后续更新中修复相关问题,并且还慷慨的给他付了一笔1万美元的奖金。

鉴于R星失误实在太低级太离谱,而这位老哥的方法又太有效,以致无数玩家称他“功德无量”。

如果平均给每个玩家节省10秒,全球500万玩家一天就能节约5000万秒,一年中,节约的总时间大概能有数十年。相当于挽救了十多个人的生命!

“事了拂衣去,不留功与名”,这位黑客大哥被无数玩家膜拜。当然大家也不忘再把R星拖出来“鞭尸”。

有人吐槽,GTA 5仅2020年就买了2000万份,累计销量更是达到1.4亿份,R星每年都能从这个项目上赚数亿美元,但是却不肯花几分钟去解决这么一个低级错误,实在可耻。

还有人抨击R星几乎从不与玩家社区互动,玩家提的意见也从来充耳不闻,直到这次被被黑客嘲讽打脸,才不得不出来表态。

事后,黑客大哥还透露了一丝身份信息,原来他人在拉脱维亚。

拉脱维亚是波罗的海国家,原来是前苏联加盟国之一。在网上搜索相关信息,可以发现“拉脱维亚黑客”,几乎是和俄罗斯黑客一样传奇神秘的存在。

有网友爆料,在拉脱维亚,普通程序员工资平均3-4k欧元(23000-31000人民币)。

而他领到的这1万美元奖金,相当于三四个月工资了。

提前领了一笔“年终奖”,黑客大哥表示很开心。同时他也说,将密切关注GTA 5未来更新,一丝不苟的检查修复情况。

不知道他还能不能从R星领走更多奖金

(注:所谓“屎山”,是程序员间流传的一个梗,指陈年累月且复杂低效的代码,因为改动成本巨大,所有人避之不及。)

一支烟的功夫,GTA 5联机版终于打开了。

「7年了!GTA 5联机版加载还是这么慢??」

Please wait forever to play
Reddit、Steam、HackerNews上,无数玩家吐槽抱怨……
进游戏少则等5、6分钟,多则20分钟。
终于,一个黑客大哥实在忍不了,用逆编译器逐条查看运行情况,终于找到原因。
原来,R星(游戏开发商RockStar)写的代码太低效,加载时,一个if语句竟然循环了19.8亿次….
幕后黑手:谁占用大量时间?
加载GTA 5 Online到底有多慢?

硬件拉满的土豪玩家请无视
Reddit相关板块发起的调查中,超过80%的玩家,都要等3分钟以上,有的甚至超过15分钟。
而且,从7年前Online上线到今天,这个情况丝毫没有改善。
暴躁的,已经骂起了脏话……

但奇怪的是,如果你选择是故事模式(单机版),加载就会快很多,感觉甚至像两个不同的工作室开发的游戏。
具体到这位黑客大哥的例子,他自己的硬件配置如下:

CPU,是老而弥坚的AMD FX-8350,2012年上市,采用“推土机”架构,超频潜力惊人。
显卡还是GTX 1070。
这样今天看起来老旧的配置,打开单机版GTA 5需要1分10秒,而加载联机版则6分钟起。
黑客大哥用了最简单的Windows任务管理器,来判断联机版GTA 5在启动时,都调用了哪些计算机资源。

在1分钟的时间分界线上,之前是加载的是单机和联机版通用的基础内容,之后是联机版独有的内容。
可以看到,联机版GTA 5,加载时调用大量CPU资源至少长达4分钟之久。
而同时,内存、GPU、硬盘的使用情况几乎没有明显变化。
所以,问题大概率出在代码上。
“R星代码写太烂!”
黑客大哥在开扒R星代码之前,就说:
我闻到一股烂代码的味道…..
为了找出到底那一部分程序卡住了CPU,他使用了工具Luke Stackwalker,对CPU任务堆栈进行采样分析。
Luke Stackwalker对于闭源应用程序,可以转存正在运行的进程堆栈,和当前指令指针的位置,以一定时间间隔建立一个调用树。
最后将数据整合,就可以得到程序运行统计数据。
从结果上看,一共有两个函数“卡住”了CPU:

于是他使用专业的代码拆解工具,给GTA 5来了一个“开膛破肚”。
沿着调用栈往下走,发现问题出在一个sscanf函数上。

sscanf的功能是读取格式化的字符串中的数据,而在GTA 5中,它正在读取的是一个10M左右,有63000多个条目的JSON文件。
这个文件到底是干什么用的?黑客大哥推测,这可能是游戏内购商店的相关内容。

在具体运行时,sscanf对于每个有效值,逐个读取每一个字符,然后返回结果,之后指针移向下一个值,循环往复……直到把10M文件全部扫一遍。
再看第二个问题,这是一个存储命令,对象是item,具体是什么不得而知。
但是保存前,有一个if语句,逐一比较item内项目的哈希值,检查它们是否出现在某一列表中。
按照他的计算,这一步if,要执行(63000^2+63000)/2 = 1984531500次!
没错,等待加载前的十多分钟里,GTA 5用你的CPU,执行了19.8亿次if命令。
如此简单粗暴的编程思路,让这位老哥哭笑不得:
既然对象有唯一哈希值,那为什么不用hash map???

(hashmap根据hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序不确定。)

至于为什么这样,有网友推测最开始,if的循环次数并没有这么多,而是随着开发,条目不断增多,最后到了积重难返的地步。

而之前的代码结构,谁也不愿意去动。

就这样,19.8亿次if,一遍遍在世界各地玩家cpu上上演。。。

这是不是堪称游戏开发史上最意外的“屎山”代码?

问题解决,加载时间节省70%

至于第一个问题,黑客大哥采用hook大法,不一一读取字符串,而是:
hook strlen
“缓存 “字符串起始和当前长度。
如果在字符串范围内函数在此被调用,返回缓存的值
至于if语句问题,就更直接了——完全跳过重复检查,利用hash map插入项目,因为这些值是唯一的。
最后的结果如下:

现在,GTA 5联机版加载,从原来的6分钟,下降到现在的1分50秒!而且,用的还是七八年前的硬件配置。
在此,应该手动@R星:你学废了吗?

这位黑客大哥在博文中没有留下任何身份信息,也没有透露用的反编译工具,但是做好事不留名的他,把打好包的工具上传到了Github,玩家通过一行代码就能下载:

git clone —recurse-submodules https://github.com/tostercx/GTAO_Booster_PoC

之后,把dll文件粘贴到游戏根目录下就OK!

惊了!一个程序员的水平能差到什么程度相关推荐

  1. 笑岔气!一个程序员的水平能差到什么程度?

    " 最近,知乎上有一则灵魂拷问"一个程序员的水平能差到什么程度?"让各位程序员们纷纷有感而发.小编精选了两个有趣的高赞回答只为抛砖引玉,欢迎大家说出你的故事! 作者:Be ...

  2. 一个程序员的水平能差到什么程度

    知乎上有一个灵魂拷问"一个程序员的水平能差到什么程度?" 让程序员纷纷有感而发. >>>> 一时吐槽爽,一直吐槽一直爽.有些童鞋看完表示了强烈认同,还有一些 ...

  3. 一个 程序员 的水平能差到什么程度?尼玛,都是人才呀... ...

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

  4. 一个程序员的水平能差到什么程度?尼玛,都是人才呀...

    点击上方"Java基基",选择"设为星标" 做积极的人,而不是积极废人! 每天 14:00 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java ...

  5. 一个程序员的水平能差到什么程度?网友:他是怎么进的公司的?

    这是发生在我朋友身上的事,下面是她的回答: 看到这问题我立刻就想回答. 本人女,在公司开发呆了一年. 小组情况: 加组长共5人,项目共6个,我和组长两人负责5个,另外三个小成员负责同1个. 突然有一天 ...

  6. 一个程序员的水平能差到什么程度?

    老板觉得公司里都是男的,缺少一点阴柔之气,想平衡一下,正巧当时互金公司倒了一大批,大批简历投到公司,老板以为自己也是技术出身,就招了一个三年工作经验的女程序员,互金出来的,要价倒是不低.我休假去了,没 ...

  7. 亲身经历 |一个程序员的水平能差到什么程度?

    本文作者:Iyan 网易工程师 Part.1 一个应届海归研究生,研究生阶段毕业设计是流体模拟,看着还不错,毕业设计是用的C++,但是面试的C++笔试题错了一大半,渲染方面的基础问题倒是答得还行.主要 ...

  8. 举些例子看看一个程序员的水平究竟可以差到什么程度?

    闲话少说直接入正题 你敢信年入百万人民币的白左能精雕细琢出这样的垃圾么(见下图) .这是16年做了五六年的情况,现在20年了,听说 终于能跑hello world了. 某西海岸IT大厂,产品失败就开源 ...

  9. 程序员猪队友,差到大家都害怕他提交代码...

    知乎上有个问题: 一个程序员的水平能差到什么程度? 下面有一个经典回答: 差到大家都害怕他提交代码 Coding Style不好的同学表示有被冒犯到.然而现实中真的有许多人光顾着刷题,却在面试中跪在了 ...

  10. 如何辨别一个程序员水平的高低?

    先来看个小故事: 小王:老大,这里怎么没有执行成功呢?代码我从其他地方拷过来的呢! 老大:报异常了没有? 小王:报了,说的是文件导入失败,可是我的文件写入的方法没有问题呀! 老大:你看看人家怎么写的? ...

最新文章

  1. java类为什么要建两个class_ClassLoader的几个概念、类和对象的解释
  2. 在Linux下怎样让top命令启动之后就按内存使用排序(或CPU使用排序)?
  3. python怎么输入文件数据库_python学习日记——文件及数据库
  4. 画师id_100位插画师是怎么过日子的?
  5. 盘点中国互联网行业10年2万多起投融资,17年投融资形势走向何处
  6. Android 性能优化——之图片的优化
  7. 记一次热更新上传补丁包失败问题
  8. PAT_B_1095_Java(25分)
  9. c语言万年历附加功能,万年历(c语言,多功能).doc
  10. python中的第三方库 cv2_cv2 python
  11. 如何利用VUE动态添加class样式
  12. oracle中print,oracle中print_table存储过程实例介绍
  13. VS2015各版本的区别
  14. uint8_t范围_uint8_t / uint16_t / uint32_t /uint64_t 是什么数据类型 - 大总结,看完全明白了...
  15. 第五届A/B组 地宫取宝 JAVA
  16. python打砖块游戏程序设计报告_打砖块游戏课程设计报告
  17. WPF实现VS界面效果
  18. SpringBoot 博客开发 个人学习(项目开始和前端页面)
  19. 要跳过磁盘检查,请在5秒内按任意键如何解决
  20. 最值得入手的五款骨传导耳机,几款高畅销的骨传导耳机

热门文章

  1. python科研向论文检索篇——提取PDF文字以供全文信息检索
  2. RS码编译matlab仿真2
  3. 电池电量检测方法-库仑计-基于LTC2941
  4. 凯文米特尼克-《欺骗的艺术》[完整中文版][DOC][PDF]
  5. java图片转视频_java实现图片转换为视频
  6. php 正态分布数据描述,啥?你的数据不呈正态分布,文章发不了:stata一键搞定...
  7. 机器人机构学基础(朱大昌)第三章部分习题答案
  8. 医院门诊管理系统——计件收费
  9. ASP.NET 2.0 探针
  10. 找不到服务器 ip 地址,无法访问此网络 找不到服务器IP地址