前言
这篇文章记录一下,我独立开发微信小游戏的过程中遇到的性能优化问题,以及对应的优化策略。如果有帮助到大家,可以来体验看看我的小游戏哦,可以扫二维码,或者在微信上搜索《影子冒险》哦。
对象池优化
在项目前期没有做对象池优化,对于对象都是生成用完后即销毁,加入对象池,避免频繁的性能消耗。- ---@generic T
- ---@class ObjectPool:T
- local ObjectPool = class("ObjectPool")
- function ObjectPool:ctor(createFunc, getFunc, recycleFunc)
- self.createFunc = createFunc
- self.getFunc = getFunc
- self.recycleFunc = recycleFunc
- self.pool = {}
- end
- function ObjectPool:Get()
- local obj = nil
- if #self.pool > 0 then
- obj = table.remove(self.pool)
- else
- if self.createFunc then
- obj = self.createFunc()
- end
- end
- if obj then
- self.getFunc(obj)
- return obj
- end
- end
- function ObjectPool:Recycle(obj)
- self.recycleFunc(obj)
- table.insert(self.pool, obj)
- end
- return ObjectPool
复制代码 Lua层避免每帧调用UnityApi
在Lua层,我有段代码会每帧对当前场景中的所有车辆位置做检查,判断是否能够销毁,其中有段代码会每帧生成一个新表,来存储当前所有的汽车对象。
可以看到后果,导致Lua内存急速飙升,并造成严重的GC:
处理方法,不再生成临时对象来存储车辆,通过倒序的方法来移除车辆:
但验证后,效果还是不太理想,内存仍然飙升,打开Unity内置的Profiler,可以看到,真正的罪魁祸首是我每帧调用了Unity层的bound做边界检测导致性能问题:
那我们接下来在Unity层封装下检测方法,避免Lua层疯狂调用Unity层的属性和方法:
Unity原生的Profiler,可以看到GC大大减少了:
LuaProfiler也可以看到内存没有飙升这么快了:
但这还不够,因为这个检查不需要这么敏感的要每帧去做检查,我们可以优化下,3秒检查一次,最终效果:
Lua避免频繁生成对象
对于事件之类的自定义的对象,也要做到尽可能的复用,例如改造前:
改造后:
Lua避免重复创建列表,新增一个clear的方法
UI刷新不要太依赖Update
UI刷新不要太依赖Update,否则带来的性能消耗超出你的想象,请看Profiler:
我的解决思路:在lua层提前封装一层Unity层的代码,将各种数据提前缓存好,避免频繁调用Unity层Api,例如Text组件,在lua层封装好当前的Text组件的字符串,在lua层检查到“修改字符串”和“当前字符串”不同,才去调用Unity层Api修改。
但我这里没有提前包,现在项目内已经到处引用着Unity层的代码了,改起来真是痛苦又操蛋!只能先暂时优化掉性能敏感的UI界面了。
在C#层检查Lua内存
可以使用collectgarbage("count")每帧输出lua内存情况,但这个输出不能放到lua层,而是放到C#层,避免影响到lua内存检测:
lua代码:
C#代码:
Lua层尽量不要在Update时频繁生成新对象
因为Lua层没有struct结构体,表生成后直接放到堆上,要是在lua层通过Update修改go位置,你就等着看内存飙升吧:
例如我这段代码:
每帧生成Vector2对象,然后查看内存情况:
改造后,lua层:
C#层:
然后有点要注意,C#层注入值类型到lua层是不缓存的(为啥不缓存,我有文章分析过了,这里不再解释,请看《tolua源码之小白剖析》系列),例如在lua层获得C#的Vector3类型,每次获得都会在lua层生成一份新的Vector3表,我这句代码就犯了这种错误,这也是导致lua内存飙升的一个罪魁祸首。
同样要将检查丢给C#层去处理。
然后同样不能在性能敏感的地方使用匿名函数,因为每次调用都会生成一次:
所以大家一定要注意,性能敏感的地方直接丢对象到lua层吧,不要丢结构体到lua层,对于lua没有结构体的概念,来自C#层的对象都是userdata,我这里又犯了这个错:
传递值类型RaycastHit到lua层,也会导致性能飙升。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |