unityのGetComponent<>の処理速度を調べた

ひもひもオンラインを作ってると、ひもの節ひとつひとつを無駄に計算しているので重くなってしまうことが多々ありました。

古来よりGetComponentは重いと言われていたことを思い出したので、

GetComponentはどれくらい重いのか調べたいと思います。

パソコンスペックと検証方法

何か処理の時間を調べられるヤーツを発見したのでそれを使います。→参考にしたサイトhttps://qiita.com/raku-lab/items/62faa5e6f9d3f060f37e

パソコンのスペックは、CPU i7-9700、メモリ16GB、グラボGTX1660です。

unityのバージョンは2021.3.8f1です。

やり方としては、Rigidbody2Dのvelocityに、1.00001fを掛け算しまくって、かかる時間を調べました。

↓プログラム(スタート関数だけ)

変数に入れるとき

void Start()
    {
      System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
      sw.Start();
      Rigidbody2D rb = GetComponent<Rigidbody2D>(); //ココでrbに入れとる!
      for(int i = 0; i < 10000000; i ++){
        rb.velocity *= 1.00001f; //ココで掛け算しとるで。
      }
      sw.Stop();
      Debug.Log(sw.ElapsedMilliseconds + "ms ←変数にコンポーネントを入れて呼び出すとき");
    }

毎回GetComponentするとき

void Start()
{
      System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); 
   sw.Start();
      for(int i = 0; i < 10000000; i ++){
        GetComponent<Rigidbody2D>().velocity *= 1.00001f; //ココで掛け算しとるで、毎回Getcomponentしてます。
      }
      sw.Stop();
      Debug.Log(sw.ElapsedMilliseconds + "ms ←毎回GetComponentする時");
}

結果は、

一千万回繰り返すと、

変数に入れるとき、1380ms。

毎回GetComponentするとき、 2443ms。となりました!!

つまり、比較すると2倍くらい重いということですね。

1回あたりの処理時間について考える

一千万回ということは、10,000,000ということですから。それぞれ一回の処理時間は、

変数に入れたのを呼び出すのは、1380/10000000 = 0.000138msということになりますね。

GetComponentで呼び出すのは、 2443/10000000 = 0.000244msということになりますね。

60FPSで動かしたいときを考える

60FPSで動かすには、1フレーム内の処理時間を16msくらいに抑えればいいので、単純に計算すると、

変数に入れたコンポーネントを呼び出すのは、1フレーム内で 115942回以下に抑える。

GetComponentで呼び出すのは、 1フレーム内で 65493回以下に抑える。

という必要があるわけですね。 (自分の環境ではね)

結論と思ったこと

やっぱりGetComponentをするほうが処理の時間はかかる。

まぁでも、1回あたりの処理速度を考えると、

シーン全体で、GetComponent を1フレーム内で「めっちゃ繰り返すやん!1000~1万回くらいやっとるやん~」というあたりから、気にすればいいかなと思いました。

~完~

ひもひもオンラインはべつに無駄Getcomponentは無かった、、単純にシステムが微妙だったオチ。