こんにちは、Unityエンジニアのオオバです。
最近多い、ふと気になったシリーズです。
昔(2~3年前)はtransform.localPosition = Vector3.zero;
のようにtransform
プロパティは直接アクセスすると、GetComponent()が内部的に実行されていて、処理負荷的に重いからキャッシュした方が良いよ!っていう話をよく聞きました。
じゃあ、最近のUnityはどうなっているか?
- transformプロパティにそのままアクセス
- GetComponent()を記述してアクセス
- transformをキャッシュしてアクセス
この3種の方法で確認します。
結果
1.transformプロパティにそのままアクセス
と3.transformをキャッシュしてアクセス
がほぼ同じくらいの負荷(ただしキャッシュが最速)。
2.GetComponent()を記述してアクセス
が最遅という結果になりました。
プロファイラーのDeep Profileで内部処理を確認してみます。
方法 | Transformアクセス処理 | ざっくり処理時間 |
---|---|---|
1.transform にそのままアクセス | 5.15ms | |
2.GetComponent 記述アクセス | 7.62ms | |
3.transform をキャッシュしてアクセス | 特になし | 3.79ms |
このようにtransformプロパティアクセスは内部的にGetComponent()ではなく、最適化され、get_transform関数が実行されているようです。
検証コードはコチラ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
public enum TransformAccessType
{
transformAccess,
GetComponentAccess,
CachedTransform,
}
public class TransformTest : MonoBehaviour
{
// インスペクタから切り替えて負荷確認
public TransformAccessType type;
Transform t;
void Update ()
{
if (t == null)
t = transform;
Profiler.BeginSample ("######");
for (int i = 0; i < 10000; i++) {
if (type == TransformAccessType.CachedTransform)
t.localPosition = Vector3.zero;
else if (type == TransformAccessType.GetComponentAccess)
GetComponent<Transform> ().localPosition = Vector3.zero;
else
transform.localPosition = Vector3.zero;
}
Profiler.EndSample ();
}
}
まとめ
ガリガリチューニングするなら、昔ながらのTransformキャッシュが最も良いですが、transformアクセスもそこそこ最適化されているため、普通に使っちゃっても大きな問題はでないだろうという見解です(状況次第)。Transformアクセスの処理方法が変わったということが分かった事が今回の調査で良かったことです。
ブログを書き終えた辺りで見つかるこのような記事。
gameObject.GetComponent() と transform の違い(または Unity における省略記法について) - Qiita
なるほど、2017.2辺り時点でtransformプロパティの最適化が入っていたようですね。
この記事が気に入ったらフォローしよう
- Unity2018.1.0f1