万年素人からHackerへの道

万年素人がHackerになれるまで殴り書きするぜ。

Unity Advent Calendar 2012 5日目 Title:「ベンチマーク」

URL: http://atnd.org/events/34621

結局5日目は私です。やはりUnity界隈は情報をシェアされる方は少ないようですね。

以前こちらで書きました「shinriyo流Unityベストプラクティス」にて、いくつかパフォーマンスが実際に速いかどうかの確証が取れないのがあったのでテストしていきます。
http://d.hatena.ne.jp/shinriyo/20121202

1. GetComponent
まずは、GetComponentの"文字列"か"コンポーネント名の"クラス名"か"ジェネリックス"かでパフォーマンステストします。

公式Document: http://docs.unity3d.com/Documentation/ScriptReference/GameObject.GetComponent.html

Inspector上では↓なっているMainCameraについてテストしていきます。

やり方としてはGetComponentTest.csを貼り付けて、自分自身だが、GetComponentTestクラスを100回とった時のパフォーマンステストです。

間違ってたら教えて下さい

まず、"文字列"

function GetComponent (type : String) : Component

GetComponentTest.cs

using UnityEngine;

public class GetComponentTest : MonoBehaviour
{
    void Start ()
    {
        float start = Time.realtimeSinceStartup;
        for (int i=0; i<100; i++) {
            GetComponent ("GetComponentTest");
        }
        float finish = Time.realtimeSinceStartup;
        Debug.Log ((finish - start).ToString ());
    }
}

→ 0.0005219579

つぎは"クラス"名
※公式ドキュメントには例がない・・・

function GetComponent (type : Type) : Component
using UnityEngine;

public class GetComponentTest : MonoBehaviour
{
    void Start ()
    {
        float start = Time.realtimeSinceStartup;
        for (int i=0; i<100; i++) {
            GetComponent (typeof(GetComponentTest));
        }
        float finish = Time.realtimeSinceStartup;
        Debug.Log ((finish - start).ToString ());
    }
}

→ 0.0001870394

最後に"ジェネリックス"
function GetComponent. () : T

using UnityEngine;

public class GetComponentTest : MonoBehaviour
{
    void Start ()
    {
        float start = Time.realtimeSinceStartup;
        for (int i=0; i<100; i++) {
            GetComponent <GetComponentTest> ();
        }
        float finish = Time.realtimeSinceStartup;
        Debug.Log ((finish - start).ToString ());
    }
}

→ 0.0003880262

んん!!!
文字列が遅いのはわかっていたが、ジェネリックスが意外と遅い・・・。
悔しいので何度もやってもクラス名に負けました。



遅い → 速い
"文字列" → "ジェネリックス" → "クラス名"

2. Find

GameObjet.Findとtransform.FindとGameObject.FindWithTagで競います。

以下の構造でおこない、"E"のGameObjectを探します。

Aにテスト用のFindTest.csを貼りますね。

まずは一番遅いと思われる"GameObjet.Find"
・FindTest.cs

using UnityEngine;

public class FindTest : MonoBehaviour
{
    void Start()
    {
        float start = Time.realtimeSinceStartup;
        GameObject obj = GameObject.Find("E");
        float finish = Time.realtimeSinceStartup;
        Debug.Log ((finish - start).ToString ());
    }
}

→ 0.0001000166
ん?意外と速い・・・

つぎは、"transform.Find"
おそらく後で.gameObjectプロパティを取得もしたいと思うのでそれも考慮します。
子を下っていくので"B/D/E"ですね。

using UnityEngine;

public class FindTest : MonoBehaviour
{
    void Start()
    {
        float start = Time.realtimeSinceStartup;
        GameObject obj = transform.Find("B/D/E").gameObject;
        float finish = Time.realtimeSinceStartup;
        Debug.Log ((finish - start).ToString ());
    }
}

→ 0.0003470182
負け・・・た??

最後に、タグ検索

「E」さんにタグ”Player”をつけて測ってみます。
インスペクタではこんな感じでタグつけました。

using UnityEngine;

public class FindTest : MonoBehaviour
{
    void Start()
    {
        float start = Time.realtimeSinceStartup;
        GameObject obj = GameObject.FindGameObjectWithTag("Player");
        float finish = Time.realtimeSinceStartup;
        Debug.Log ((finish - start).ToString ());
    }
}

→ 0.0001149774



遅い → 速い
transform.Find → GameObject.FindWithTag → GameObjet.Find

思ったのと全く逆!!

納得行かない、transform.Findはたどり方を書いてる分速いと思ったのに遅かったです。
.gameObjectを外して以下の用にして受け皿の「GameObject obj = 」を消してみました。

transform.Find("B/D/E");

しかし、0.0003219843


Vector3のメモリ確認もやりたかったですが、明日の方がいなさそうなので明日用にとっときますw
では、次の方宜しく。