Unity
performance

Unity Transform取得時間を削減する

Transformを取得しUpdateやFixedUpdateの中で毎フレーム計算するような処理を書くことは多いだろう
特に大量のObjectを処理する場合Transformの取得が処理を食うこともある

検証コード

TransformObject.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TransformObject : MonoBehaviour 
{
    Transform _Transform;

    void Awake()
    {
        _Transform = transform;
    }

    public void GetTransform()
    {
        var position = transform.position;
    }

    //thisを付けたバージョン
    public void GetThisTransform()
    {
        var position = this.transform.position;
    }

    //AwakeでキャッシュしたTransformから取得する
    public void CacheTransform()
    {
        var position = _Transform.position;
    }
}
TransformTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TransformTest : MonoBehaviour 
{
    static readonly int OBJECT_NUM = 10000;
    TransformObject[] _transformObjects = new TransformObject[OBJECT_NUM];

    void Start () 
    {
        //TransformObjectを1万個生成する
        for (int i = 0; i < OBJECT_NUM; i++) {
            var go = new GameObject ();
            _transformObjects[i] = go.AddComponent<TransformObject> ();
        }
    }

    void Update () 
    {
        //毎フレーム各関数を呼び出す
        for (int i = 0; i < _transformObjects.Length; i++) {
            _transformObjects [i].GetThisTransform ();
        }

        for (int i = 0; i < _transformObjects.Length; i++) {
            _transformObjects [i].GetTransform ();
        }

        for (int i = 0; i < _transformObjects.Length; i++) {
            _transformObjects [i].CacheTransform ();
        }
    }
}}

検証結果

image.png
キャッシュしたTransformを使うのが圧倒的に速いことがわかる

image.png
もう少し詳しく見てみると、Transform.get_position()やTransform.INTERNAL_get_position()にかかる時間は3種とも大差ないが
キャッシュしない場合は「Component.get_transform()」が呼ばれており処理時間がかかっている。

GameObject編

以下のコードを追記してGameObjectに対しても同様のテストを行った

TransformObject.cs
    public void GetGameObject()
    {
        var go = gameObject;
    }

    public void GetThisGameObject()
    {
        var go = this.gameObject;
    }

    public void CacheGameObject()
    {
        var go = _GameObject;    //_GameObjectはAwakeでキャッシュしている
    }

image.png

やはりキャッシュすると圧倒的に速くなる

結論

TransformやGameObjectは毎回取得せずにキャッシュすべし