UdonSharpにおけるVector3の値操作
が、パフォーマンスやメモリ使用にどのような影響を与えるのかを調査しました。
通常のUnity(MonoBehaviour)環境では、Vector3の値を一度変数としてキャッシュし、必要に応じて再利用することで、new
の回数を減らし、処理速度とメモリ効率の向上が図れます。
これは一般的なテクニックとして広く知られています。
しかし、同様の手法がUdonSharp環境でも有効なのかについては検証していなかったため、詳細な調査を行いました。
using UnityEngine;
public class TestMono : MonoBehaviour
{
private Vector3 v2 = Vector3.zero;
private void Update()
{
var v = Vector3.zero;
// GC Alloc 0B Time 5.52ms Self 5.52ms
for (int i = 0; i < 1000000; i++)
{
var v3 = Vector3.zero;
}
// GC Alloc 0B Time 5.55ms Self 5.55ms
for (int i = 0; i < 1000000; i++)
{
var v3 = new Vector3(0, 0, 0);
}
// GC Alloc 0B Time 5.55ms Self 5.55ms
for (int i = 0; i < 1000000; i++)
{
v2 = new Vector3(0, 0, 0);
}
// GC Alloc 0B Time 2.59ms Self 2.59ms
for (int i = 0; i < 1000000; i++)
{
v.x = 0;
v.y = 0;
v.z = 0;
}
// GC Alloc 0B Time 2.22ms Self 2.22ms
for (int i = 0; i < 1000000; i++)
{
v2.x = 0;
v2.y = 0;
v2.z = 0;
}
// GC Alloc 0B Time 1.23ms Self 1.23ms
for (int i = 0; i < 1000000; i++)
{
v.x = 0;
}
}
}
using UdonSharp;
using UnityEngine;
public class TestUdonSharp : UdonSharpBehaviour
{
private Vector3 v2 = Vector3.zero;
private void Update()
{
var v = Vector3.zero;
// GC Alloc 26.7MB Time 622.97ms Self 588.32ms
for (int i = 0; i < 1000000; i++)
{
var v3 = Vector3.zero;
}
// GC Alloc 26.7MB Time 644.20ms Self 605.54ms
for (int i = 0; i < 1000000; i++)
{
var v3 = new Vector3(0, 0, 0);
}
// GC Alloc 26.7MB Time 643.85ms Self 605.13ms
for (int i = 0; i < 1000000; i++)
{
v2 = new Vector3(0, 0, 0);
}
// GC Alloc 80.1MB Time 1853.69ms Self 1728.58ms
for (int i = 0; i < 1000000; i++)
{
v.x = 0;
v.y = 0;
v.z = 0;
}
// GC Alloc 80.1MB Time 1712.12ms Self 1600.13ms
for (int i = 0; i < 1000000; i++)
{
v2.x = 0;
v2.y = 0;
v2.z = 0;
}
// GC Alloc 26.7MB Time 844.04ms Self 811.57ms
for (int i = 0; i < 1000000; i++)
{
v.x = 0;
}
}
}
- UdonSharpでは、Vector3の値操作すべてにおいてGC Allocが発生します。
- プロパティ(x, y, z)を個別に変更する処理では、各プロパティ操作ごとにGC Allocが発生し、処理時間も非常に大きくなります。
v.x=123;
とnew Vector(123, 0, 0);
はGC Allocと処理時間はほぼ同等です。 (内部処理では何かしら違いがある可能あり)- UdonsharpでVector3値操作する場合、
new Vector3(...)
で値をまとめて設定するのがGC効率も良く、軽量です。