🐼

UdonSharpで各処理ごとのGCアロケート調査

2022/06/26に公開

経緯

以前Udonで別コンポーネントにアクセスした時のGCアロケートを調べた時の派生です。
各処理のGCアロケート具合をProfilerで調べました。
https://zenn.dev/panda_nakami/articles/20220416-vrchat-udon-alloc

結果要約

Vector3/Quarternionを触ってもGCアロケート発生しない。
Networking.LocalPlayer.GetTrackingData()なんかでもGCアロケート発生しない。
案外GCアロケートは発生しない様子。

ただしnew Vector3()なんかしたら当然GCアロケート発生する。

参考にしていた以下サイトの情報と異なりVector3/Quarternion周りを触ってもGCアロケートしなかったのはSDK(VRChat)のバージョンアップの影響かもしれない。
https://qiita.com/toRisouP/items/16bd06aa303a1bb1a747#uは別コンポーネントのメソッド呼び出しがコスト

環境

- バージョン
Unity 2019.4.31f1
VRCSDK VRCSDK3-WORLD-2022.02.16.19.13_Public
UdonSharp UdonSharp_v0.20.3
ClientSim #9205b40a

Vector3アクセス

GCアロケート発生しない。

コード
private Vector3 _TmpVector = new Vector3();

private void Update()
{
	for(int i = 0; i < 1000; i++) {
		_TmpVector.x = 0;	//set
		float n = _TmpVector.x;	//get
	}
}
  • Profiler

Quarternionアクセス

GCアロケート発生しない。

コード
private Vector3 _TmpVector = new Vector3();
private Quaternion _TmpQuo = Quaternion.Euler(0, 0, 0);

private void Update()
{
	for(int i = 0; i < 1000; i++) {
		_TmpVector.x = 0;
		_TmpQuo.eulerAngles = _TmpVector;	//set
		Vector3 n = _TmpQuo.eulerAngles;	//get
	}
}
  • Profiler

transformへのposition/rotationアクセス

GCアロケート発生しない。
(ついでにgameObjectからtransform取得もGCアロケート発生しない)

コード
private Vector3 _TmpVector = new Vector3();
private Quaternion _TmpQuo = Quaternion.Euler(0, 0, 0);
private void Update()
{
	for(int i = 0; i < 1000; i++) {
		_TmpVector.x = 0;
		_TmpQuo.eulerAngles = _TmpVector;

		//ついでにgameObjectからtransform取得の調査
		gameObject.transform.position = _TmpVector;	//set position
		gameObject.transform.rotation = _TmpQuo;	//set rotation

		float n = gameObject.transform.position.x;	//get position
		float n2 = gameObject.transform.rotation.eulerAngles.x;	//get rotation
	}
}
  • Profiler

Networking.LocalPlayer.GetTrackingData()アクセス

GCアロケート発生しない。
(ついでにNetworkingからLocalPlayer取得もGCアロケート発生しない)

コード
private Vector3 _TmpAngle = new Vector3();
private Quaternion _TmpQuo = Quaternion.Euler(0, 0, 0);
private void Update()
{
	for(int i = 0; i < 1000; i++) {
		VRCPlayerApi.TrackingData tData 
			= Networking.LocalPlayer
				.GetTrackingData(VRCPlayerApi.TrackingDataType.Head);

		_TmpAngle = tData.rotation.eulerAngles;	//トラッキングデータから角度取得
		_TmpAngle.x += 1;			//角度更新
		_TmpQuo.eulerAngles = _TmpAngle;	//Quarternion角度設定
		transform.position = tData.position;	//set position
		transform.rotation = _TmpQuo;		//set rotation
	}
}
  • Profiler

new Vector3()

GCアロケート発生する。(あたりまえ)

コード
private Vector3 _TmpVector = new Vector3();

private void Update()
{
	for(int i = 0; i < 1000; i++) {
		_TmpVector = new Vector3();
	}
}
  • Profiler

this.gameObject, this.transform取得

GCアロケート発生しない。
予め変数として用意されている様子。

udon assembly
__0_this_intnl_UnityEngineGameObject: %UnityEngineGameObject, this
__0_this_intnl_UnityEngineTransform: %UnityEngineTransform, this

Discussion