本文章仅供稿于知乎、UWA和我个人网页,未经允许禁止转载。
大家好,我是舒航,现任职于心动网络,主要负责RO的优化工作。今天主要想和大家分享一下,我这段时间在LuaCPU性能优化方面的一些经验。
上一篇文章主要讲的是写一个LuaProfiler的思路,即如何快速定位到内存和CPU问题。而这一篇则着重于介绍如何写好Lua代码,已经优化的一些经验。在我优化RO和隔壁项目组的CPU性能时候,发现CPU性能问题非常个性化,两个项目遇到的问题截然不同。而通用的Lua性能优化的Tips,往往并不能解决问题。所以这篇文章的前部分是我总结的我优化过程中常见的性能问题,后半部分是实际优化案例的一个分析,希望这样的一个形式能帮助到大家。
常见优化
常见优化主要是参考了Lua作者Roberto Ierusalimschy所写的Lua性能优化建议。
1. 使用局部变量
这个点是绝大部分Lua性能问题产生的原因,尤其是和一个频繁调用的函数组合,会产生大量的开销。总的来说,我们在一个频繁调用的函数内,应该避免重复地去查询Table,应该把Table内我们常用的值缓存起来。这里的值通常有两种:
- 函数
- 对象
虽然Lua是first-class,但是我发现实际使用中,大家意识上还是认为函数有别于其他值。所以分开来列举,方便大家对号入座。
使用局部变量是优化Lua性能的一条重要准则。
不管是函数还是对象,不管是Lua自身的库,还是我们自己写的,在Lua中都是储存在_G中的某个节点下。当我们调用一个函数/对象的时候,Lua首先会去他们的表中查找到这个函数/对象,而我们使用局部变量的话,由于Lua的局部变量是储存在寄存器(这里的寄存器不对应CPU的寄存器)内的,所以这个访问就会快很多。更严重的是,如果使用的是父类的函数/对象,还会触发__index,这样不仅会有额外的耗时还有内存开销。
尽量使用局部变量是一个容易避免,但是对于不熟悉Lua的人又很容易出现的问题,有些时候这也会造成比较严重的性能问题。比较常见的就是写UI的同学在一个定时器或者一个循环内,使用GetComponent来获取组件然后进行一些操作。由于没有用变量缓存起来,每次用完了就抛弃,再用再获取。不仅会造成很大的耗时,还会造成很大的内存开销。而写UI的工作又容易被大家所忽视,所以目前为止,我发现大部分项目这一块都有优化的空间。
这里提供了一段缓存Lua函数的代码(摘自Roberto原文):
|
|