代码对性能的影响

前段时间,有渠道反馈我的游戏在安卓模拟器上玩帧率非常低,但前段时间却没有这个问题。于是我就开始各种查性能。

遇到这种帧率低的问题,第一反应一般都是考虑到渲染上的问题。但我可以比较明确的知道,最近项目没有加什么特殊资源,也没有改过渲染的方式,按道理不会突然出现渲染方面的问题。于是从代码的层面查找,比如用Unity自带的profiler工具去分析cpu耗时等,终于发现是在一个提示玩家可以领取奖励的红点功能里面出了问题。

实际上问题是一直存在,是由于设计上的漏洞,导致抛事件通知界面显示红点时没有做必要的过滤。在一开始需要显示提示红点的界面还少的时候,没有感觉出问题。但后来需要显示红点的界面越来越多之后,问题就凸显出来了。

举这个例子,我主要是想说明,很多时候我们会第一时间考虑游戏性能问题是渲染等比较底层的东西导致的,总考虑是不是机器的性能不行导致卡。但实际上,这种渲染问题一般只会出现在项目初期的时候,而且都是通过制订合理的美术资源标准和渲染方案就能解决。到了项目的后期,出现性能问题一般都是程序代码引起的。

代码里面能引起性能问题的地方很多,比如每帧处理的Update方法,事件机制,字符串的处理,文件读写,序列化和反序列号,循环遍历,等等,都会引起很多性能问题。更不用说比较复杂的算法执行了,比如寻路和AI之类。

就拿业务逻辑上很经常用到的读表操作来说,假如有一个功能需要查一张行数上千的表格,有些人可能会直接每次就把需要的key作为参数传进查找方法里面,然后就开始遍历表,找到数据匹配的字段返回。这个做法对不对?这个无法回答,因为不知道查这张表的频率究竟有多高。如果查找的频率非常低,比如整个游戏周期就查一两次的(例如游戏启动时读一次的基础配置),那就没什么大问题,也不需要缓存下来浪费内存了(毕竟能省一点是一点)。如果查询的频率有点高,不过不是所有值都需要用到的(比如道具表,有上千个道具,但常用的也就几十个),那就可以把已经查询过的值缓存起来。最后,如果是经常需要用而且大部分值都需要读取到的,甚至可以整个表都缓存起来。

上面举的查表例子,实际上就是一个cpu和内存之间的权衡了,也就是所谓的时间与空间之间的博弈。想适当的减少运算,一般都需要牺牲内存空间来做缓存,但如果缓存得太多,又会导致内存使用过大而卡或者闪退。怎样取舍,首先需要根据实际情况来决定,然后就是需要经验了。

作为一个程序员,写程序除了需要完成功能,还需要对自己写的逻辑耗时比较了解。一般的游戏帧率在30fps,也就是说每一帧的时间只有33毫秒,如果是要求高一点的游戏,帧率达到60fps,那么每一帧可用的时间才16毫秒。如果由于某个运算量大的方法,一下就卡了1秒,整个游戏就会明显的卡顿很厉害了。

很具体的做法以后有机会再逐一和大家探讨,从大的方面来说,我觉得以下几点可以从写代码的习惯上提高一些代码执行的效率:

1.尽量减少遍历,用哈希索引代替数组遍历

2.数组和字典的插入、删除等都是比较消耗性能,因为会触发Resize。字典的查询如果在字典的key非常多的时候,也是会消耗效率的。

3.尽量少进行字符串操作,不要直接用加号连接字符串。

4.变量能重复利用的就尽量不要声明太多的临时变量,特别是在循环里面声明临时变量。

5.使用事件机制的时候必须在事件不需要监听的时候移除掉,不然事件监听越积越多,会是一个很大的消耗。

6.注意内存的分配,如果方法里面频繁的有gc分配,会让gc的频率加快,你会感觉游戏没过多久就卡顿一下。

7.注意一下打印输出的数量和频率,在发布正式版本的时候,最好把打印屏蔽掉。

8.复杂计算或者频繁查询的结果最好缓存下来,减少重复的计算量。

9.尽量减少读写文件的次数。大容量的文件可以考虑切割一下。

10.如果每帧需要处理的东西太多,可以考虑做分帧处理。

11.多从宏观的角度思考问题,不要总是拘泥于某个小功能的实现,说不定会发现更通用和高效的解决办法。

做项目的过程中,一般都是很多个程序员协助下把项目做出来。如果其中一个人的代码习惯不好,很有可能就会导致整个项目效率低下,而且由于问题往往出在业务逻辑层,还不好快速的定位,需要逐个功能排查。所以作为一个程序员,真的很应该多考虑一下自己写的东西究竟有没有问题,而不仅仅满足于把某个功能需求做完就算了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值