1.资源加载或反序列化为什么会带来开销
2.资源加载优化的方法
1.资源加载或反序列化为什么会带来开销
1).资源加载或反序列化为什么会带来开销
a.资源加载
Resources加载、AB包加载、Addressables加载、UnityWebRequest加载、WWW加载、File加载等等
b.反序列化数据
Json、XML、二进制、ScriptableObject等等
c.在进行资源加载或反序列化时带来的主要开销有
- IO开销
磁盘或网络读取会有I/O等待, 等待数据从磁盘或网络加载到内存, 这个过程会阻塞主线程(特别是同步加载时)
- 解析开销
加载成功后又需要进行数据解析或反序列化, 用于匹配内部类的结构; 对于部分资源可能还会存在解压缩过程(比如AB包的
LZ4和LZMA格式)
- 内存分配初始化开销
对于一些资源对象, 我们需要分配C++引擎对象(比如Mesh、Texture、AnimationClip等), 并且还需要对对应对象进行初始
化这个过程也会带来消耗
资源加载和数据反序列化会消耗CPU, 是因为它们本质上是把文件里的原始字节流转化为可用对象的过程, 涉及I/O、解压
解析、内存分配和对象初始化; 这些工作目前只能由CPU完成, 而且往往集中在主线程执行, 所以会造成明显的性能开销
这个过程可以简单整理为"读文件—>变对象—>进场景"; 我们的优化思路就是把这个过程做得更轻更分散更可复用
2.资源加载优化的方法
1).减小序列化对象
让需要被读出来的对象体积更小、结构更简单; 这样解析就会更快, 计算压力就会更低
举例: 配置文件尽量用2进制代替文本配置(Json、XML等)让配置文件体积更小, 结构更简单, 可以提升处理效率
2).异步加载 + 分帧实例化
不要在主线程同步卡着等待, 而是通过异步API加载资源(避免主线程阻塞卡顿), 并且加载成功要实例化时分帧处理(避免主
线程阻塞卡顿)
举例:
a.利用Resources、AB包、Addressables、UnityWebRequest等加载方式中的异步方法加载资源
b.资源加载成功后, 当需要实例化n个对象时分多帧去进行处理
3).缓存
把付出昂贵代价加载出来的结果暂存在内存中, 下次直接复用, 相当于用内存换性能
举例:
对于资源对象, 我们可以用合适的容器将其缓存在内存中; 下次如果还要使用, 直接获取使用即可, 对于已经实例化的场景
中的对象, 我们可以利用缓存池不停复用它们
注: 缓存内容要在合适的时候进行清理, 避免内存泄漏