Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

게임공장

유니티 null 체크 유의사항 본문

Articles

유니티 null 체크 유의사항

짱승_ 2021. 3. 16. 19:50

원문 : https://overworks.github.io/unity/2019/07/16/null-of-unity-object.html

  • 유니티 오브젝트는 C++로 작성된 네이티브 객체의 래퍼
    • Object.Destroy()를 사용하면 제거되지만 C#으로 래핑한 유니티 오브젝트는 GC가 수집하기 전까지 살아있다
      • 이 상태를 "fake null" 이라 한다
      • 유니티에서 오버로딩된 ==, != 연산자는 네이티브 객체의 존재 여부까지 판단하여 비용이 많이 든다
    void Start()
    {
        Stopwatch sw = new Stopwatch();

        Transform t = transform;
        sw.Start();
        for (int i = 0; i < 100000000; ++i)
        {
            t = transform;
        }
        sw.Stop();

        Debug.Log("cache test 1: " + sw.Elapsed);
    }
    private Transform _cachedTransform;

    public Transform cachedTransform
    {
        get
        {
            if (_cachedTransform == null)
            {
                _cachedTransform = transform;
            }
            return _cachedTransform;
        }
    }

    void Start()
    {
        Stopwatch sw = new Stopwatch();

        Transform t = cachedTransform;
        sw.Start();
        for (int i = 0; i < 100000000; ++i)
        {
            t = cachedTransform;
        }
        sw.Stop();

        Debug.Log("cache test 2: " + sw.Elapsed);
    }
  • 위와 같은 이유로 위 2개의 코드 중 첫번째 코드가 더 빠르다
    • 그만큼 오버로딩된 null 체크가 상당한 비용을 발생시키는 것
  • public이나 SerializeField로 선언되어 인스펙터에서 노출된 후 바인딩되지 않은 오브젝트는 "fake null" 이다 (주의)
  • 해결 방안
    • 단순한 캐싱이나 생성된 이후 파괴되지 않을 싱글턴같은 경우에는 닷넷 오브젝트로서 null 비교를 하는 것이 좋다
      • object.ReferenceEquals(_cachedObject, null)
    • Destroy 한 이후에 오브젝트에 null을 명시적으로 넣어주자
    • 주의할 점은 아무 경우에나 닷넷 오브젝트의 null만 비교하면 안된다는 것
반응형