検証結果
※結果は Unity エディタ上で 10 回テストしたものの平均値、単位は秒
※Unityのバージョンは4.3.4
オブジェクト | 検索方法 | 1,000 回 | 10,000 回 | 100,000 回 |
---|---|---|---|---|
100 | Find | 0.004392 秒 | 0.027789 秒 | 0.252738 秒 |
100 | FindGameObjectWithTag | 0.000693 秒 | 0.004147 秒 | 0.018733 秒 |
100 | FindObjectOfType | 0.070080 秒 | 0.622304 秒 | 5.801984 秒 |
1,000 | Find | 0.037534 秒 | 0.357311 秒 | 3.543825 秒 |
1,000 | FindGameObjectWithTag | 0.000655 秒 | 0.002315 秒 | 0.018519 秒 |
1,000 | FindObjectOfType | 0.157907 秒 | 1.552248 秒 | 16.20919 秒 |
10,000 | Find | 0.429361 秒 | 4.274960 秒 | 42.64132 秒 |
10,000 | FindGameObjectWithTag | 0.000346 秒 | 0.001686 秒 | 0.016235 秒 |
10,000 | FindObjectOfType | 1.375987 秒 | 14.24521 秒 | 長いので省略 |
まとめ
Find 関数と FindObjectOfType 関数は
オブジェクト数や検索回数に比例して遅くなりました
特に FindObjectOfType 関数は全ゲームオブジェクトの
全コンポーネントを検索するためかとても遅かったです
FindGameObjectWithTag 関数は
オブジェクト数や検索回数が増えたとしてもとても高速でした
なので、ゲームオブジェクトの検索速度がボトルネックになった場合は
検索方法をタグによる検索にすると処理速度が改善するようです
検証用スクリプト
using System; using UnityEngine; /// <summary> /// Find 関数の処理速度を計測するスクリプト /// </summary> public sealed class FindTest : MonoBehaviour { public int LoopCount = 1000; // 1 回のテストで Find 関数を実行する回数 public int TestCount = 10; // テストの回数 public int NumGameObjects = 100; // 検索対象のオブジェクトの数 /// <summary> /// ゲーム開始時に指定された数分のオブジェクトを生成します /// </summary> private void Awake() { var types = new PrimitiveType[] { PrimitiveType.Capsule, PrimitiveType.Cube, PrimitiveType.Cylinder, PrimitiveType.Plane, PrimitiveType.Quad, PrimitiveType.Sphere, }; for (int i = 0; i < NumGameObjects; i++) { GameObject.CreatePrimitive(types[UnityEngine.Random.Range(0, types.Length)]); } } /// <summary> /// Find, FindGameObjectWithTag, FindObjectOfType 関数を実行するボタンを表示します /// </summary> private void OnGUI() { DrawButton(0, "Find", () => GameObject.Find("Player") ); DrawButton(100, "FindGameObjectWithTag", () => GameObject.FindGameObjectWithTag("Player") ); DrawButton(200, "FindObjectOfType", () => GameObject.FindObjectOfType<BoxCollider>() ); } /// <summary> /// 指定された関数を実行するボタンを表示します /// </summary> private void DrawButton(float buttonY, string buttonText, Action findAct) { if (GUI.Button(new Rect(0, buttonY, Screen.width, 100), buttonText)) { var sum = 0f; for (int i = 0; i < TestCount; i++) { var time = Time.realtimeSinceStartup; for (int j = 0; j < LoopCount; j++) { findAct(); } time = Time.realtimeSinceStartup - time; sum += time; } var avg = sum / TestCount; Debug.Log(avg); } } }