简体   繁体   中英

What is the fastest way to get GameObject reference?

Let's say my script is defined as given below.

public GameObject _GameObject;

private void Start()
{
[![enter image description here][1]][1]
    _GameObject = gameObject;
}


Would this execute faster?

public void SetActive(bool value)
{
  [1]: https://i.stack.imgur.com/S60FB.jpg
    gameObject.SetActive(value);
}

Or this?

public void SetActive(bool value)
{
    _GameObject.SetActive(value);
}

In Unity 4.x and below, the cache method would be significantly faster. In those versions, MonoBehaviour.transform and MonoBehaviour.gameObject were not actually fields; rather, "under the hood" they behaved like properties with an attached accessor.

Thus accessing the gameObject property would make a method call to Component.get_gameobject() via the accessor. Of course, a method call naturally imposes more overhead than a simple memory access. (Transform was worse; apparently the accessor actually invoked the GetComponent method to return the value!)

This is why you will often see veteran Unity developers caching these values.

I have it on good authority that this process has been streamlined in Unity 5 for better performance; using the built-in properties will still create a very small amount of overhead but it is reportedly insignificant.

Source: https://blogs.unity3d.com/2014/06/23/unity5-api-changes-automatic-script-updating/

I assumed that caching the variable is faster than using the gameObject variable from the Component class and a simple test proved that to be true. That's because caching it will give you the reference rather than using gameObject which uses the get accessor to return the reference. Not sure if getting the reference requires a native function call but that's a possibility. Using get accessor is slower than direct reference access.

Let's say you have 1 million scripts calling gameObject.activeSelf or through the cached version _GameObject.activeSelf .

Test Result:

gameObject: 54 ms

Cached _GameObject: 30 ms

Software/Hardware tested on:

  • Unity 5.6.0f3
  • Windows 10 Pro
  • MacBookPro11,4
  • 16 GB RAM

Does it matter?

In a normal app, maybe not. In a game, yes. Removing 24ms from a game is a good improvement depending on the kind of Game.

Test script:

public GameObject _GameObject;

void Start()
{
    Application.runInBackground = true;

    int iterations = 1000000;

    //TEST 1
    Stopwatch stopwatch1 = Stopwatch.StartNew();
    for (int i = 0; i < iterations; i++)
    {
        bool active = gameObject.activeSelf;
    }
    stopwatch1.Stop();

    //TEST 2
    Stopwatch stopwatch2 = Stopwatch.StartNew();
    for (int i = 0; i < iterations; i++)
    {
        bool active = _GameObject.activeSelf;
    }
    stopwatch2.Stop();
    //SHOW RESULT
    WriteLog(String.Format("gameObject: {0}", stopwatch1.ElapsedMilliseconds));
    WriteLog(String.Format("Cached _GameObject: {0}", stopwatch2.ElapsedMilliseconds));
}

void WriteLog(string log)
{
    UnityEngine.Debug.Log(log);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM