背包卡顿的地方主要有这几个地方,第一个就是打开背包的时候,会明显卡顿,然后就是切换背包里面的页签也会,还有一个就是使用背包里面的道具,或者出售道具的时候。
这个卡顿只有在开启ILRuntime热更的时候,正常的还是很流畅的。但是我又不能去优化ILRuntime,于是对于这几个地方使用unity自带的Profiler查看是什么原因造成的。
调了全道具,然后打开背包的时候,发现耗时1900ms,哇,有点吓人啊。看了下发现主要是背包道具排序和FairyGui创建组件这两块,fairygui这块没法处理,于是目标放在道具排序上。我们背包的排序比较函数,这个函数被调用了2w多次,所以里面比较小的时间消耗在这个基数上也会变得很大。我们排序比较方式是通过排序规则的优先级来给不同的道具加上不同的值,最后比较值的大小来进行排序的。比如品质的优先级大于类型,那么品质高的+10000,然后类型中优先级高的+5000这样。在这一块发现吃时间的居然是里面的引用类型的属性(之前一直没有这方面的意识),缓存了一波发现效果不是很明显,才减少了200ms,想了好一会才猛然发现,为啥我直接把道具比较时算的值缓存起来呢,这样下次碰到这个道具的时候就直接取出来就好了,不用在算一次了。于是我用字典将道具ID和比较时算的值存起来。发现一下减少到了600ms,这样感觉还能接受了。
接下来就是使用道具,这块发现主要也是刷新背包的时候,而且还有个比较严重的问题是刷新的时机,这块刷新是在服务器通知背包道具改变的时候刷新的,使用道具的话,尤其是使用盒子之类的道具,在盒子被使用后,服务器会回一条消息告诉你盒子被使用掉了,然后马上又有一条使用盒子获得道具消息回来,也就是会刷两次背包。这块我使用了延迟一帧在刷新处理的。
出售道具,瞅了下也是因为对背包排序导致的,但是出售道具不需要重新对背包排序,于是这块我去掉了排序。
最后就是切换页签了,这个发现还是因为排序导致的,服了,每次切换不同类型的道具的时候,都会对这类道具进行一次排序刷新。处理是做了缓存,不用每次切换的时候排序刷新,而是在服务器道具改变消息回来时,根据道具的类型,指定的排序刷新这类道具的列表。这样处理的话,就是拿空间去换时间了,不过效果还是很明显的。
总结:这次让我知道原来调用引用类型的属性或者方法放回引用类型会有消耗的,只是消耗很小,如果次数大了后,就会出现问题,其次就是仔细考虑功能具体在哪些时候调用生效,不能笼统的调用,需要细化到具体的时机。