
100000개 실행 기준
using System.Collections.Generic;
using System.Diagnostics;
using Unity.VisualScripting;
using UnityEngine;
public class FrameTester : MonoBehaviour
{
Dictionary<Collider, FrameTester> tester = new();
Collider cachedCollider;
FrameTester cachedComp;
void Start()
{
// 자기 자신 등록
cachedCollider = gameObject.GetComponent<Collider>();
cachedComp = GetComponent<FrameTester>();
tester[cachedCollider] = cachedComp;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
RunComparison(new Ray(transform.position, Vector3.up));
}
}
void RunComparison(Ray ray)
{
const int len = 100000;
double gTime = 0;
double dTime = 0;
// -----------------------
// GetComponent 방식
// -----------------------
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < len; i++)
{
if (Physics.Raycast(ray, out var hit, 10f))
{
var comp = hit.collider.GetComponent<FrameTester>();
comp.asdf(1.24f, 45.23f);
}
}
sw.Stop();
gTime = sw.Elapsed.TotalMilliseconds;
UnityEngine.Debug.Log($"[GetComponent] {len}회 실행: {gTime} ms");
// -----------------------
// Dictionary 방식
// -----------------------
sw.Restart();
for (int i = 0; i < len; i++)
{
if (Physics.Raycast(ray, out var hit, 10f))
{
if (tester.TryGetValue(hit.collider, out var comp))
{
comp.asdf(1.24f, 45.23f);
}
}
}
sw.Stop();
dTime = sw.Elapsed.TotalMilliseconds;
UnityEngine.Debug.Log($"[Dictionary] {len}회 실행: {dTime} ms");
}
public void asdf(float a, float b)
{
float result = a * 1210210;
result -= 21312 * b;
}
}
테스트코드
GetComponent와 Dictinoary에 캐싱하여 판별하는 케이스
위 테스트 결과에서 20ms 밖에 차이가 안나지만
O(n)인 GetComponent와
O(1)인 딕셔너리를 비교했을때
GetComponent하는 게임오브젝트에 각종 renderer와 animator, navmesh, colider +1(몸통,머리)를 추가 할 시
검색 속도가 더 느려질 것으로 보이므로 GameManager에 캐싱해서 사용하는 방법을 사용
다만 value값에 interface를 사용하는게 메모리와 유지보수측면에서 좋지 않을까 싶다.