유니티 게임 오브젝트의 tag를 체크하여, tag에 따라 다른 동작을 해주려고 할 때
tag를 체크하는 코드를 다음과 같이 작성했더니 경고 메세지가 떴다.
// 1. equality operator 로 비교
if (gameObject.tag == "MyTag")
{
// do something...
}
경고 메세지는 다음과 같았다.
info UNT0002: Comparing tags using == is inefficient.
equality operator 로 비교하는 것은 비효율적이라고 한다.
대안이 있을 것 같아서 조금 찾아보니,
다음과 같이 CompareTag() 로 비교하는 것이 조금 더 효율적이라고 한다.
// 2. CompareTag 메소드로 비교
if (gameObject.CompareTag("MyTag"))
{
// do something...
}
둘의 차이가 무엇이길래 효율면에서 차이가 날까?
이 차이는 GameObject 의 tag 가, 멤버변수가 아닌 프로퍼티임으로부터 나오는 차이로 보인다.
위 프로퍼티의 getter 가 호출되는 순간, string 을 복사 생성한다고 한다.
이는 곧, 메모리 할당 및 복사로 인한 부하를 야기하고, GC 의 일거리를 하나 늘어나도록 만든다.
(추측컨데, GameObject의 tag 는 내부적으로는 별도의 integer/hash 값으로 저장되어 있고
사용자가 tag 프로퍼티를 통해 string 을 get 할 때에는
별도의 테이블로부터 string을 복원/복사해서 리턴하는 형태가 아닐까 싶다.)
CompareTag() 함수는 동적할당 없이 tag 비교가 가능하도록 구현된 메소드라 효율적이다.
"Unity 5 Game Optimization by Chris Dickinson" 에 의하면 27%의 성능 향상 효과를 볼 수 있다고 한다.
(전달받은 string 파라미터에서 hash 값을 생성하여 비교하는 형태일까?)
또, CompareTag() 와 == 사이에는 중요한 차이점이 하나 더 있는데,
CompareTag() 는 인자로 전달받은 string 이 실제로 존재하는 태그인지 확인하는 동작까지 포함한다.
존재하지 않는 태그를 CompareTag() 함수로 비교할 경우 다음과 같은 에러가 발생한다.
오타, 혹은 리팩토링 간 삭제된 태그를 오용하는 경우까지 체크가 가능할 것으로 보인다.
성능 면에서도, 안정성 면에서도
CompareTag() 함수를 사용하지 않을 이유가 없는 것 같다.
Visual Studio refactor 기능은 Alt + Enter 를 통해
== / != 를 CompareTag() 로 자동변경해주는 기능을 제공하고 있으니 십분 활용하면 좋겠다.
참조 :
github.com/JetBrains/resharper-unity/wiki/Use-CompareTag-instead-of-explicit-string-comparison
answers.unity.com/questions/200820/is-comparetag-better-than-gameobjecttag-performanc.html
'Unity' 카테고리의 다른 글
Unity : Terrain에서 Prefabs Tree가 추가되지 않을 때 (충돌박스 있는 나무 심기) (0) | 2020.12.25 |
---|---|
Unity : 상속받은 User-defined 클래스에 중단점이 안걸릴 때 (0) | 2020.12.14 |
Unity : 충돌 후 이동방향이 삐딱할 때 (0) | 2020.12.13 |