打开GTA 5竟要跑19.8亿次if语句!黑客嘲讽R星代码烂,修改后直接省70%加载时间

打开GTA 5竟要跑19.8亿次if语句!黑客嘲讽R星代码烂,修改后直接省70%加载时间本文转载自量子位一支烟的功夫,GTA5联机版终于打开了。「7年了!GTA5联机版加载还是这么慢??」△PleasewaitforevertoplayReddit、Steam、HackerNews上,无数玩家吐槽抱怨……进游戏少则等5、6分钟,多则20分钟。终于,一个黑客大哥实在忍不了,用逆编译器逐条查看运行情况,终于找到原因。原来,R星(游戏开发商RockStar)写的代码太低效,加载时,一个if语句竟然循环了19.8亿次….幕后黑手:谁占用大量时间?加

大家好,又见面了,我是你们的朋友全栈君。

本文转载自 量子位

一支烟的功夫,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值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序不确定。)

问题解决,加载时间节省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!

博客原文
https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times-by-70/

Github地址:
https://github.com/tostercx/GTAO_Booster_PoC

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/131279.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 网站的类型有哪些(9种管理类型)

    一HttpEntity的类型 1  BasicHttpEntity     代表底层流的基本实体。通常是在http报文中获取的实体。他只有一个空参的构造方法。刚创建时没有内容,长度为负值。需要通过两个方法,把值赋进去。  /** *BasicHttpEntity *@throwsIOException */ public…

    2022年4月18日
    42
  • invoke方法的使用

    invoke方法的使用

    2022年6月12日
    31
  • Android中根据coverage.ec文件生成报告

    Android中根据coverage.ec文件生成报告关于android中的代码覆盖率,可以参考我前几篇文章:Android手工测试代码覆盖率增强版Android手工测试的代码覆盖率AndroidUI自动化测试的代码覆盖率官方生成代码覆盖率报告的流程gradle为android提供的插件生成代码覆盖率的报告流程为首先在应用目录的生成coverage.ec文件(比如我们的应用package为com.wuba.wuxian.android_0

    2022年7月20日
    12
  • Install Mplayer and Multimedia Codecs (libdvdcss2,w32codecs,w64codecs) on ubuntu 11.10

    Install Mplayer and Multimedia Codecs (libdvdcss2,w32codecs,w64codecs) on ubuntu 11.10

    2021年8月17日
    58
  • Android 加载串口通信读取信息时 AndroidStudio loadLibrary失败「建议收藏」

    Android 加载串口通信读取信息时 AndroidStudio loadLibrary失败「建议收藏」static{ System.loadLibrary(“serial_port”); }今天想连接串口做一个新功能但是连接串口加载库的时候总是找不到serial_port库1:项目结构是这样的库文件不多说github很多Android.mk##Copyright2009CedricPriscal##LicensedundertheApacheLicense,Version2.0(the”License”);#you…

    2022年7月15日
    17
  • 指令字长,机器字长,存储字长的关系_指令字长的概念

    指令字长,机器字长,存储字长的关系_指令字长的概念指令字长、存储字长、机器字长、时钟周期、机器周期、指令周期、取址周期、存取周期的关系考研做题途中遇到这些问题,发现自己掌握的很模糊,遂写下此篇,加深记忆。1、机器字长、存储字长、指令字长机器字长:CPU一次能够处理的数据的位数。通常等于寄存器的位数。例子:windows64位/32位,这里的64位和32位指的就是该操作系统的机器字长。存储字长:计算机存储器中一个存储单元可以存储的位数。例子:某某计算机按照字节编址,即说明该计算机的存储字长为1B=8位。指令字长:计算机内一条指令的位数。这里通常指

    2022年8月31日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号