Preview
주제: 성능 저하를 일으키는 요인
- 사용하지 않는 생명 주기 함수
- Find 계열 함수
- Debug.Log
- LINQ
- 순서를 고려하지 않은 연산식
- Camera.main
- 문자열 덧셈
- 반복문에서 new WaitForSeconds
- ObjectPool 미사용
- 빈번한 Boxing & Unboxing
사용하지 않는 생명 주기 함수
- 일단 생명 주기 함수가 등록되면 내부에 코드가 없어도 매 프레임마다 호출되므로 리소스 낭비
- 사용하지 않는 생명 주기 함수는 반드시 삭제 필요
Find 계열 함수
- 메모리에 있는 모든 게임오브젝트와 컴포넌트에 대해 검사하기 때문에 자주 호출될수록 성능 부하 큼
- 빌드 단계의 코드에서 최대한 제거 필요
참고 자료: https://docs.unity3d.com/kr/2022.3/Manual/BestPracticeUnderstandingPerformanceInUnity7.html
Debug.Log
- 빌드에도 디버그 로그가 포함되어 보안에 취약
- 빌드에서 제거되지 않고 실행되므로 리소스 낭비
- 필요하다면 Debug.LogAssertion() 사용, 빌드 시에 제거됨 (간혹 제거되지 않는 경우 발생)
- 에디터에서만 동작하고 빌드 시에는 제거되는 클래스 직접 구현하여 사용(가장 권장되는 방법)
LINQ
- 동일한 로직을 LINQ가 아닌 for 나 if로 대체할 수 있음
- 동일한 로직을 for나 if로 구현하면 성능 향상, 데이터 커지고 반복 횟수 증가할수록 차이 증가
- .NET Framework 상위 버전에서는 LINQ 성능 최적화되어 크게 차이나지 않지만 Unity에서는 아직 4.8(구버전) 사용하므로 성능 좋지 않음
참고 자료: https://medium.com/swlh/is-using-linq-in-c-bad-for-performance-318a1e71a732
순서를 고려하지 않은 연산식
- 연산 횟수, 피연산자의 타입을 고려하여 효율적인 연산식 작성 필요
ex) Vector3 연산
private Vector3 dir; // (1, 1, 1)
private float speed = 2;
// Time.deltaTime을 3이라고 가정(원래는 약 0.0027)
private void Start()
{
// 1번
// Vector3(2, 2, 2) 3번 => (6, 6, 6) => 6번
transform.position += dir * speed * Time.deltaTime;
// 2번
// (2*3) 1번 => (6, 6, 6) => 4번
transform.position += speed * Time.deltaTime * dir;
}
Camera.main
- GameObject 중 MainCamera로 태그된 오브젝트를 가져옴
- Update에서 사용 시 매번 카메라를 찾아오므로 그전에 미리 캐싱하여 사용하기
private Camera cam;
private void Start()
{
cam = Camera.main; // Good
}
private void Update()
{
Camera.main...; // Bad
}
문자열 덧셈
- + 연산자로 문자열을 덧셈하여 사용 시 메모리 재할당하며 리소스 낭비 & 메모리 파편화
- 새로운 문자열을 할당할 공간을 찾고 재할당, 이전 문자열 공간은 참조 해제하며 GC 작동하며 이중으로 리소스 사용
- 문자열 보간이나 StringBuilder 사용 권장
반복문에서 new WaitForSeconds
- Coroutine 호출 시 반복문에서 new WaitforSeconds 사용하면 매번 새로운 객체를 생성
- 캐싱하여 사용하면 성능 향상, GC 호출 횟수 감소
private WaitForSeconds waitSeconds = new WaitForSeconds(1f); // 캐싱
IEnumerator co()
{
while (true)
{
yield return new WaitForSeconds(1); // Bad
yield return waitSeconds; // Good
}
}
ObjectPool 미사용
- 자주 생성되고 파괴되는 오브젝트들을 objectpool로 관리하지 않으면 성능 저하 매우 큼
- 설계상 오브젝트 풀에 없을 때 추가로 생성하고 반환하는 경우 부모오브젝트 아래 자식으로 오브젝트 풀 생성하지 않기
-- 오브젝트 풀로 새로 생성된 객체를 계층에서 부모 오브젝트의 자식으로 배치하려면 트리 구조 변경 필요하므로 오히려 성능 저하, 그냥 최상위 오브젝트로 계속 생성되게 설계하기
- 오브젝트 풀 내 제한된 개수로만 운용하는 경우면 자식오브젝트로 묶어서 관리해도 OK
빈번한 Boxing & Unboxing
- Boxing: 값 -> 참조
- Unboxing: 참조 -> 값 (참조가 해제되므로 GC 호출)
- 불필요한 boxing & unboxing 사용 지양
'내일배움캠프 > TIL' 카테고리의 다른 글
| [내배캠][Unity6기][TIL] 최종 프로젝트 중간 기록 (1) (0) | 2024.12.05 |
|---|---|
| [내배캠][Unity6기][TIL] Behavior Tree 구조 설계 (3) (0) | 2024.12.04 |
| [내배캠][Unity6기][TIL] UGS 데이터 로드 (0) | 2024.12.02 |
| [내배캠][Unity6기][TIL] Behavior Tree 구조 설계 (2) (0) | 2024.11.30 |
| [내배캠][Unity6기][TIL] Behavior Tree 구조 설계 (1) (0) | 2024.11.29 |