반응형
Notice
Recent Posts
Recent Comments
«   2024/04   »
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
Archives
Today
Total
관리 메뉴

Do Something IT

[Unity3D] Overview: Performance Optimization (성능 최적화) 본문

Unity3D

[Unity3D] Overview: Performance Optimization (성능 최적화)

아낙시만더 2011. 8. 9. 11:42
반응형

유니티는 최대한 동적 타입을 사용하지 않도록 설계가 되어 있습니다. 만들어진 모든 스크립트는 net DLL 형태로 컴파일이 진행된 후(자바의 바이트 코드와 비슷한 형태로), 초기 실행 시간에 컴파일이 완료됩니다. NET 분야를 공부하신 분들은 이 부분을 어느 정도 이해하실 겁니다.

 

유니티 관련 문서를 찾아보면, 동적타입보다는 정적 타입을 사용하도록 권장하고,문제가 되지 않는다면 자옹적으로 정적 타입으로 바꾸는 것을 시도한다고 적혀있습니다. 예를 들어서

 

var foo=5;

 

라고 적힌 코딩은 자동적으로 정적 타입으로 컴파일이 진행됩니다. 일반적인 자바 또는 동적 타입 방식 언어처럼 변수 룩업테이블을 만들어서 실제 생성된 변수( 대부분 힙 영역)를 참조하는 형태로 래핑하지 않습니다. 이렇게 정적 타입으로 변경함으로써 얻은 실행 속도는 동적 타입 기반보다 20배 정도 속도 향샹이 있습니다.(유니티 문서 참고)

 

결국 유니티 스크립터는 동적 타입을 사용하지 않도록 최선을 다해야 합니다. 흔한 대표적인 사례가 GetComponent 함수 사용시에 발생합니다.

 

function Start(){

  var foo = GetComponent(MyScript);

  foo.DoSomething();

}

  

foo 변수는 데이터 타입이 정의되지 않았습니다. 또한 GetComponent 역시 특정 데이터 타입를 반환하는 형태가 아니라 Object 타입을 반환하는 형태입니다. 즉 유니티 컴파일러입장에서 동적 타입을 사용할수 밖에 없습니다. 따라서 룩업테이블이 실행시간에 생성되며 정말 자바스럽게 운영됩니다.  성능 향상은 기대할수 없습니다.

 

function Start(){

var foo:MyScript = GetComponent(MyScript);

foo.DoSomething();

}

 

위 코디에서는 foo의 데이터 타입을 지정했습니다. 조금의 변화지만, 유니티 컴파일러에게는 동적 타입으로 컴파일하느냐 정적 타입으로 컴파일하느냐를 결정하는 중요한 힌트가 됩니다. 실제 위 코딩은 정적 타입으로 컴파일되며, 이전 코딩보다 훨씬 성능이 좋습니다. 적어도 룩업테이블을 찾지 않으니까요.

 

 

#pragma strict

 

비쥬얼 베이직이나 최근 액션스크립트에서 비슷한 기능을 본듯한데, 해당 Predefined 구문은 명시적인 타입 캐스팅을 하도록 강요합니다. 즉 유니티 컴파일러는 데이터 타입을 알아서 캐스팅하지 않습니다. 해당 구문은 결국, 스크립트 제어 능력이 되는 개발자에게는 권장합니다. 문제없이 코딩을 작성한다면 동적 타입은 거의 없어질테니까요.

 

#pragma strict

 

function Start(){

  var foo:MyScript = GetComponent(MyScript) as MyScript;

   foo.DoSomething();

}

 

위와 같이 직접 as 구문을 활용해서 타입 캐스팅을 해야 합니다. 암시적이라곤 찾아볼수 없는 코딩이지만, 유니티 컴파일러는 위와 같은 코딩을 무척 좋아할겁니다.

 

 

실제 유니티 코딩 샘플에서 자신도 모르게 GetComponet 함수를 호출하거나 제공된 속성 변수를 활용해서 룩업 테이블을 활용하는 경우가 있습니다. 예를 들면 다음 코딩입니다.

 

function Update(){

   transform.Translate(0,0,5);

}

 

상단 코딩은 gameObject 속성에의 transform를 사용합니다. 문제는 gameObject에서 transform 객체를 얻는 과정에서 룩업 테이블을 경유합니다. 따라서 다음과 같은 코딩을 작성한다면 역시 성능이 좋아집니다.

 

private var myTransform:Transform;

 

function Awake(){

   myTransform=transform;

}

 

function Update(){

     myTransform.Translate(0,0,5);

}

 

 

유니티의 내장 배열은 성능이 아주 좋습니다. 또한 캐시 적중률이 좋도록 설계되었습니다. 뭐 간단히 말해서 메모리가 한 블럭 내부에 존재하도록 잘 설계가 되었습니다.

 

private var positions:Vector3[];

 

function Awake(){

    position = new Vector3[100];

}

 

 

위 코딩에서 처럼 new 구문으로 메모리를 힙에 생성할수 있으며 100만큼 사이즈를 확보했습니다. 이제 position를 사용하면 아주 빠르게 작동할겁니다.

 

 

유니티 스크립트는 CoRoutine 함수를 지원합니다. 마치 쓰레드와 유사합니다. 프레임 애니메이션에 영항을 주지 않고, 복잡한 연산을 진행할수 있으며, 프레임 기반 프로그램에서 많이 필요한 기능입니다. 이 부분에 대해서는 다음에 기회가 되면 정리하겠습니다.




 
반응형
Comments