浅谈务实的游戏程序员该如何做优化

近期面试了一些后端程序,问了些优化方面的问题,我发现很多人都答不好这个问题。

先来定义一下,什么样的程序员能称之为务实。对于游戏项目来说,进度是至关重要的一个因素,所以一个务实的程序员,应当能快速解决遇到的问题,快速交付稳定的代码,而可具备一定可以维护性,以应对策划多变的需求。

举个例子,在面试中有个候选人跟我说,他做过一个背包的优化,就是原本是的结构是字典的形式,如{name:”道具1”, lv:1, num:99},为了节省空间,他把这个结构改成数组的形式:[“道具1”, 1, 99],以此减少了冗余的key。然后在外面再封装了api去访问字典的字段。

问题来了,这样的优化真的有必要吗。可能这个优化,对于背包这个系统确实减少了一半的内存。但是,我们需要考虑一个问题是,这个背包系统,在整个玩家数据里,真能占那么大比例吗。假如,背包的数据只占到总内存的2%,那这个优化做完了之后,变成1%,从整体来看,只让内存占用下降了1%,却带来了代码维护上的困难,以及拖慢的项目的进度,这是得不偿失的一件事。

以下是我关于优化的一些观点:

1.在游戏的研发阶段,优化是优先级最低的,我们不应该主动去做优化,开发效率和可维护性是高于优化的,除非某一个功能遇到了瓶颈。

2.我们需要了解客户端和服务器的瓶颈分别是什么:

客户端的瓶颈通常是在内存,不仅缓存了逻辑数据,还有图片,模型,字体这些资源,在客户端的进程通常只能分配非常有限的内存,所以客户端的优化通常是用时间换取空间。需要用到数据或者资源,才动态加载。

而服务端的瓶颈通常是CPU,服务器需同时面对成千上万的客户端,对于某些特定的框架(如skynet),如果CPU有一个核跑满100%,就会导致部分功能出现明显卡顿。所以优化的方式倾向于空间换时间,在服务器启动的时候,把数据都准备好缓存起来,这样不仅逻辑更简单,更能节省运行时的CPU运算。

3.优化是无尽头的,我们在做优化之前,应该先明确所有前置条件,如数据的规模量,调用的频率。举例:服务器承载的玩家数量上限是多少,场景有多大,最多需要容纳多少个对象,玩家操作的频率。所有的优化应该紧紧围绕这些前置条件来进行,不要做吃力不讨好的优化。比如,1个服就容纳1000个玩家,排行榜就只取top100,这玩意你说要用到红黑树去排序,不纯扯(我就干过这种蠢事,还傻傻的改造了红黑树的算法去实现排名)

4.除了性能的优化,还有代码结构的优化,或者叫重构代码。重构我认为应该尽早进行,让接口变得清晰,好用,可以延迟屎山的到来(虽然我依旧认为不可避免的所有的项目都会变成屎山)。

总结:优化这个东西,适可而止,能不做就不做。这个世界就是一个草台班子,老板不会因为你提高了1%的性能给你加鸡腿。