Unity

[Unity] 스크립트 최적화에 대한 기록

sungjine 2023. 12. 11. 20:35
반응형

 

1. LINQ를 사용하지 않는다.

    LINQ는 사용하기는 쉽지만, 알고리즘을 직접 만들어 사용하는 것보다 일반적으로 더 많은 자원이 필요하다.

 

2. 최대한 GC가 동작하지 않도록 한다.

    GC(가비지 컬렉터)는 자동 메모리 관리자로 메모리 할당 및 해제를 관리한다. 자동으로 관리되기 때문에 개발자는 편하지만 동작하게 될 때 많은 자원을 사용하게 된다. GC가 동작하는 시점은 시스템의 메모리가 부족해지거나 관리되는 힙에 허용되는 임계값을 초과하는 경우이다. 즉 사용되지 않는 메모리가 많아질수록 GC가 동작하게 될 여지가 많아지기 때문에 이를 막아야 한다.

 

3. boxing에 주의한다.

    boxing이란 int, bool, 등과 같은 값 형식 변수를 참조 형식 변수로 래핑하는 것으로 래핑하게 되면 메모리에 할당되고 결국 GC가 동작하기 때문이다.

 

4. 큰 구조체는 함수로 전달하지 않는다.
    구조체는 함수에 직접 전달되면 해당 내용이 새로 만든 인스턴스에 복사된다. 때문에 구조체의 크기가 클 경우 문제가 될 수 있다.

 

5. Update() 함수와 같이 반복해서 호출되는 곳에서는 GetComponent(), Find() 류의 함수를 여러 번 사용하지 않는다.

   해당 함수를 사용하면 많은 자원을 사용하게 된다. 때문에 한 번 함수를 호출할 때 반환된 내용을 캐싱하여 사용한다.

   5-1 Camera.main 또한 호출될 때마다 Object.FindObjectWithTag를 호출하므로 사용 중인 카메라를 직접 참조한다.

 

6. 빈 콜백함수를 생성하지 않는다.

   실행하는 작업이 없더라도 생성되어 있으면 호출이 되고 이때 비용이 많이 든다.(Update(), FixedUpdate(), 등...)

 

7. SendMessage(), BroadcastMessage() 사용하지 않는다.

    SendMessage(), BroadcastMessage()는 직접 함수 호출보다 1,000배 더 느릴 수 있다.

 

8. GameObject의 문자열 속성을 사용하여 문자열을 비교하지 않는다.

    일반적인 문자열로 비교하면 문제가 없지만 GameObject의 문자열 속성(name, tag)을 사용하여 비교하면 GC가 동작하기 때문에 해당 속성과 문자열을 비교하지 말아야 한다.

    이를 회피하기 위한 방법은 tag의 경우 CompareTag() 함수를 활용하고 name의 경우 비교하고자 하는 변수를 const를 활용해 상수로 만들어서 비교하면 된다.

 

9. 제곱근의 경우 자원을 많이 소모하기 때문에 제곱을 활용할 수 있다면 제곱근 대신 제곱을 사용한다.

 

10. 문자열 조합을 피한다.

   문자열을 조합하면 가비지가 쌓이기 때문에 GC가 자주 동작할 수 있다. 이를 회피하기 위한 방법으로 StringBuilder를 사용한다.

 

11. 풀링을 사용한다.
    풀링은 지속적인 개체 생성 및 제거에 드는 비용을 줄이기 위한 기술이다. 이 것은 개체를 지속해서 만들고 제거하는 대신, 비활성화한 개체를 풀에 할당한 후 이 풀에서 개체를 꺼내어 사용하고 사용한 개체는 비활성화하여 다시 풀에 넣는다.

 

참고 : https://learn.microsoft.com/ko-kr/windows/mixed-reality/develop/unity/performance-recommendations-for-unity?tabs=openxr

 

반응형