유니티 C# : 박싱과 언박싱




C#은 object가 모든 데이터를 다룰 수 있도록 하기 위해

모든 데이터 형식, 심지어 프로그래머들이 만드는

데이터 형식마저도 자동으로 object 형식을 상속 받는다.

즉, object는 모든 데이터 형식의 base class가 된다.




object 형식은 참조 형식이기 때문에 힙에 데이터를 할당한다.

반면, int나 double은 값 형식이기 때문에 스택에 데이터를

할당한다. 하지만 앞서 모든 데이터는 object를 상속받는다고

했는데 어떻게 값 형식의 데이터를 object에 담을 수 있는가?




object 형식은 값 형식의 데이터를 힙에 할당하기 위해

박싱 (boxing) 기능을 제공한다.


object a = 20;


20은 힙에 할당 되고, a는 그 주소를 참조한다. (박싱)




반대로 힙에 있던 값 형식 데이터를 값 형식 객체에

다시 할당해야 하는 경우가 있는데

이를 언박싱(unboxing)이라고 한다.


object a = 20; //// 박싱

int b = (int)a //// 언박싱


a는 박싱되어 20이 저장되어 있는 힙을 참조하고 있다.

b는 a가 참조하고 있는 메모리로부터 값을 복사한다. (언박싱)




정리하자면

박싱 : 값 형식을 참조 형식으로 변환

언박싱 : 참조 형식을 값 현식으로 변환




박싱의 과정 : 

1. 값 타입을 힙에 생성하기 위해 메모리를 힙 영역에 생성

2. 값을 힙 영역에 할당된 메모리로 복사

3. 참조할 변수에 할당된 메모리 주소를 할당




언박싱의 과정 :

1. 박싱값인지 확인

2. 박싱된 값이라면 값 타입 변수에 복사

3. 박싱한 메모리와 언박싱한 메모리 2개 존재 ( 가비지 발생 )


주의 : 모든 객체가 값 형식으로 언박싱이 될 수 없고, 이전에 박싱이 된

데이터에 한하여 언박싱이 가능하다. 또한 박싱하기전의 타입을 따라야 한다.




박싱/언박싱(boxing/unboxing)

MSDN 에 의하면 값 형식을 박싱할 때에는 완전히 새로운

개체가 만들어져야 하며, 이러한 작업에는 할당 작업보다

최대 20배의 시간이 걸린다고 한다. 언박싱 또한 캐스팅

과정이 할당 작업보다 4배의 시간이 걸릴 수 있다고 나와있다.




보시다시피 엄청난 성능상의 단점이 있다.

하지만 박싱/언박싱의 편리성 때문에 간혹 쓰이기도 한다.

--> ArrayList , 헤쉬테이블이 박싱/언박싱의 대표적인 예이다.


성능상의 단점을 감수하면서까지 쓸 필요는 없다고 생각한다.

리스트나 딕셔너리로도 충분히 대체할 수 있기 때문에

이를 공부하여 적절히 사용하는 방법이 좋을 것 같다.




+ Recent posts