Blink

纸上得来终觉浅,绝知此事要躬行

Unity中GetComponent的三种方式效率比较

获取组件的三种方式

在Unity中获取物体上的组件有三种方式
– public Component GetComponent (string type);
– public Component GetComponent (Type type);
– public T GetComponent ();

目前我们用的最多的是第三种,通过泛型获取组件。既然有三种方式可以获取组件,那么在正常的开发过程中应该使用哪种方式获取组件效率最高,接下来就测试一下三种方式分别执行一百万次,比较一下他们的效率差别。为了使结果相对客观和准确,我们分别获取Unity中自带的组件和我们自己写的组件,分别对比其效率

准备工作

为了方便测试,下面贴一个进行了简单封装的获取执行时间的类代码

using System;
using System.Diagnostics;

public class CustomTimer : IDisposable
{
    private Stopwatch watch = null;
    private string label = null;

    public CustomTimer(string label)
    {
        this.label = label;
        watch = Stopwatch.StartNew();
    }

    public void Dispose()
    {
        long time = watch.ElapsedMilliseconds;
        watch.Stop();
        watch = null;
        UnityEngine.Debug.LogFormat("{0}测试耗时<color=#ff0000>{1}</color>ms", label, time);
    }
}

测试Unity自带组件获取

这里我们直接将脚本挂在摄像机上,获取摄像机上的AudioListener组件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript1 : MonoBehaviour
{
    private const int COUNT = 1000000;  // 执行次数
    private AudioListener component;    // 存储获取的组件

    private void Start()
    {
        Test1();
        Test2();
        Test3();
    }

    /// <summary>
    /// String方式
    /// </summary>
    private void Test1()
    {
        using (new CustomTimer("string方式"))
        {
            for (int i = 0; i < COUNT; i++)
            {
                component = GetComponent("AudioListener") as AudioListener;
            }
        }
    }

    /// <summary>
    /// typeof方式
    /// </summary>
    private void Test2()
    {
        using (new CustomTimer("typeof方式"))
        {
            for (int i = 0; i < COUNT; i++)
            {
                component = GetComponent(typeof(AudioListener)) as AudioListener;
            }
        }
    }

    /// <summary>
    /// 泛型方式
    /// </summary>
    private void Test3()
    {
        using (new CustomTimer("generics方式"))
        {
            for (int i = 0; i < COUNT; i++)
            {
                component = GetComponent<AudioListener>();
            }
        }
    }
}

《Unity中GetComponent的三种方式效率比较》
点击运行,输出的如下结果
《Unity中GetComponent的三种方式效率比较》
对比结果,发现使用泛型的方式耗时最少,一百万次耗时58毫秒,string方式和typeof方式相差不大,都在120毫秒左右。由此得出获取自带组件使用泛型的方式是效率是最高的,字符串次之,typeof的方式效率最差。
那么结果真的如此吗?如果是我们自己写的组件,得出的结果是否也和上面的一样呢?接下来验证一下获取自定义组件

测试自定义组件获取

测试总体过程还是和上面的一样,不同的是这次我们需要在摄像机上挂在一个我们自己写的组件,下面我们就自己建一个TestComponent的组件(就是创建一个TestComponent脚本,保存默认即可)如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestComponent : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }
}

接下来将上面的测试脚本获取的AudioListener组件都改为TestComponent

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript1 : MonoBehaviour
{
    private const int COUNT = 1000000;  // 执行次数
    private TestComponent component;    // 存储获取的组件

    private void Start()
    {
        Test1();
        Test2();
        Test3();
    }

    /// <summary>
    /// String方式
    /// </summary>
    private void Test1()
    {
        using (new CustomTimer("string方式"))
        {
            for (int i = 0; i < COUNT; i++)
            {
                component = GetComponent("TestComponent") as TestComponent;
            }
        }
    }

    /// <summary>
    /// typeof方式
    /// </summary>
    private void Test2()
    {
        using (new CustomTimer("typeof方式"))
        {
            for (int i = 0; i < COUNT; i++)
            {
                component = GetComponent(typeof(TestComponent)) as TestComponent;
            }
        }
    }

    /// <summary>
    /// 泛型方式
    /// </summary>
    private void Test3()
    {
        using (new CustomTimer("generics方式"))
        {
            for (int i = 0; i < COUNT; i++)
            {
                component = GetComponent<TestComponent>();
            }
        }
    }
}

运行,输入结果如下:
《Unity中GetComponent的三种方式效率比较》
这次发现,字符串方式的耗时惊人,和另外两个不在一个数量级上,泛型的方式依旧是耗时最短的

结论

  1. 在开发过程中推荐使用泛型方式获取组件
  2. 获取自定义组件效率比获取自带组件效率低
  3. 应当避免在工程中使用字符串方式获取组件,除非不用考虑效率问题(例如编辑器功能开发)
点赞

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注