抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Unity 性能优化

Unity版本为2022.3.34,本文所有的测试均在Editor下进行

尽管我认为,性能远远没有实现重要,提前优化、过度优化、虚空优化,之会影响开发效率,不过还是记录一下我最近学到的一些关于Unity性能优化的小技巧

脚本优化

测试工具

public class CustomTimer: IDisposable
{
private string _name;
private int _count;
private Stopwatch _stopwatch;
public CustomTimer(string name, int count)
{
_name = name;
_count = count;
if (_count <= 0)
{
_count = 1;
}
_stopwatch = Stopwatch.StartNew();
}
public void Dispose()
{
_stopwatch.Stop();
UnityEngine.Debug.Log($"{_name} took {_stopwatch.ElapsedMilliseconds}ms for {_count.ToString("N0")} iterations, average time: {_stopwatch.ElapsedMilliseconds / _count}ms");
}
}

GetComponent的方式

测试三种获得Component的方式

ComponentTest comp = null;
using (new CustomTimer("GetComponent(string)", testCount))
{
for(int i = 0; i < testCount; i++)
{
comp = (ComponentTest)GetComponent("ComponentTest");
}
}
using (new CustomTimer("GetComponent<>", testCount))
{
for(int i = 0; i < testCount; i++)
{
comp = GetComponent<ComponentTest>();
}
}
using (new CustomTimer("GetComponent(typeof(ComponentTest))", testCount))
{
for(int i = 0; i < testCount; i++)
{
comp = (ComponentTest)GetComponent(typeof(ComponentTest));
}
}

经测试,几乎无差别(貌似老版本会有区别,用string最慢)

GetComponent(string) took 136ms for 1,000,000 iterations, average time: 0ms
GetComponent<> took 115ms for 1,000,000 iterations, average time: 0ms
GetComponent(typeof(ComponentTest)) took 177ms for 1,000,000 iterations, average time: 0ms

比较go是否为null

int ans = 0;
using (new CustomTimer("Empty", testCount))
{
for(int i = 0; i < testCount; i++)
{
ans++;
}
}
Debug.Log(ans);
ans = 0;
using (new CustomTimer("!=", testCount))
{
for(int i = 0; i < testCount; i++)
{
if (go != null)
{
ans++;
}
}
}
Debug.Log(ans);
ans = 0;
using (new CustomTimer("ReferenceEquals", testCount))
{
for(int i = 0; i < testCount; i++)
{
if(!System.Object.ReferenceEquals(go, null))
{
ans++;
}
}
}
Debug.Log(ans);

经测试,直接比较是!= null更慢

Empty took 21ms for 100,000,000 iterations, average time: 0ms
!= took 445ms for 100,000,000 iterations, average time: 0ms
ReferenceEquals took 22ms for 100,000,000 iterations, average time: 0ms

检索Tag

int ans = 0;
using (new CustomTimer("string tag", testCount))
{
for(int i = 0; i < testCount; i++)
{
if (go.tag == "Player")
{
ans++;
}
}
}
Debug.Log(ans);
ans = 0;
using (new CustomTimer("CompareTag", testCount))
{
for(int i = 0; i < testCount; i++)
{
if (go.CompareTag("Player"))
{
ans++;
}
}
}
Debug.Log(ans);

直接比较tag字符串更慢

string tag took 162ms for 1,000,000 iterations, average time: 0ms
CompareTag took 70ms for 1,000,000 iterations, average time: 0ms

Update

  • 停止远处GO的脚本update

  • 分层update

序列化

重写序列化,只保留一些必须的参数,尽量存储简单的数据结构,反序列化时自行从Resources.LoadAsync()中加载出来

图形优化

SRP Bather

评论