티스토리 뷰

Programming

Generic 과 Boxing&Unboxing

신잼 2021. 11. 24. 10:28

Generic 과 Boxing/Unboxing

  • Boxing 과 Unboxing 과정에서 계산 과정 비용이 들기 때문에 빈번하게 발생하면 성능에 이슈가 있다.
  • Generic은 런타임 시점에서 인스턴스를 형성할 때 Generic Type으로 지정되어 인스턴스를 할당하기 때문에 Boxing이 아닌 처음부터 Reference type의 ValueType을 할당할 수 있다.

Generic Programming(제너릭 프로그래밍)

https://www.reddit.com/r/ProgrammerHumor/comments/cx5u2a/generic_cup/

일종의 알고리즘으로 타입이 나중에 지정되는 개념이다. 컴퓨터 프로그래밍의 한 스타일이며, 필요할 때 매개변수로 제공되면서 특정 유형으로 인스턴스화된다.

data type을 추상화 함으로써 코드 재사용성을 높히고 유지보수를 용이하게 한다.

Design Patterns의 저자들은 이 방법이 특히 위임과 결합할 때 매우 강력하지만, 정적 소프트웨어보다 이해하기 어렵다는 점을 강조한다.

Benefits

  • 코드가 간결해 진다.
  • 재사용성이 높아진다.
  • type safety를 보장한다.
    • i.e. List 은 string원소를 갖는 list로 제약한다.
  • Compile 단계에서 type check가 가능하다
    • Runtime error보다는 compile에서 고치는게 더 쉽다
  • object를 사용 하는 것 보다 빠르다
    • boxing/unboxing을 피하기 때문(.net에서는ㄴ value type을 reference type으로 변경해야한다(그 반대도 포함))
    • 요구되는 reference type으로 object 변환을 피하기 때문

Typescript

without generics

stack 클래스로 모든 타입의 데이터를 받는 pushItem 메서드가 있다.

class Stack
{
  private stack: any[];
    pushItem(item){
        this.stack.push(item);
    }
}
var newStack = Stack();
var aString = "A String";
var aNumber = 100;
var aPerson = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
newStack.pushItem(aString);
newStack.pushItem(aNumber);
newStack.pushItem(aPerson);

array를 순회 하거나 정렬, 필터링 등을 하게 되면 문제가 된다. 이러한 문제들은 runtime에서만 확인이 될 수 있어 문제가 된다.

with generics

class GenericStack<T>;
{
  private stack: T[]; 
  function pushItem(item: T) { 
  this.stack.push(item); 
  }
}
var numberStack = GenericStack<Number>(); 
var stringStack = GenericStack<String>(); 
var aString = "A String"; 
var aNumber = 100; 
var aPerson = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};

// These will pass the typescript compiler
stringStack.pushItem(aString); 
numberStack.pushItem(aNumber);

// But these would all fail.
numberStack.pushItem(aPerson);
numberStack.pushItem(aString);
stringStack.pushItem(aPerson);
stringStack.pushItem(aNumber);

Python

  • Python에서는 Generic을 따로 구현 할 필요가 없다.
    • 덕 타이핑을[각주:1] 사용하기 때문에 여러 타입을 다루는 문법이 필요가 없다
    • 3.5부터 typed variant를 만들 수 있다.
      from typing import TypeVar, Generic, List
       
       T = TypeVar('T')
       
       class Stack(Generic[T]):
           def __init__(self) -> None:
               # Create an empty list with items of type T
               self.items: List[T] = []
       
           def push(self, item: T) -> None:
               self.items.append(item)
       
           def pop(self) -> T:
               return self.items.pop()
       
           def empty(self) -> bool:
               return not self.items​

        # Construct an empty Stack[int] instance
        stack = Stack[int]()
        stack.push(2)
        stack.pop()
        stack.push('x')        # Type error
       

Boxing/Unboxing

C#, .net을 기준으로 작성됩니다

[(left)Boxing,(right)Unboxing](https://gtrekter.medium.com/boxing-and-unboxing-in-c-b9d58216a3f7)

TL;DR

  • Boxing: value type을 reference type으로 변환 하는 것
  • Unboxing: reference type을 value type으로 변환 하는 것
EX: int i = 123;
    object o = i;// Boxing
    int j = (int)o;// UnBoxing
  • value types: int, char ...
  • Reference types: Classes, interfaces, arrays, objects ...

문제점

  • Boxing, unboxing 과정에서 시간이 더 소요
  • Unboxing에서 메모리 낭비

Python은 모든 것이 object이면 모두 heap에 있을까?

Yes, all Python objects live on the heap (at least on CPython.)

 


Reference

Generics

Boxing/Unboxing

반응형

'Programming' 카테고리의 다른 글

No Operation(no-op, nop, noop)  (0) 2022.01.11
Golang 공부 중  (0) 2021.11.25
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   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
글 보관함