Boxing i unboxing.

W zeszłym poście pisałem o strukturach w c#. Jednym z ważnych efektów ubocznych jest boxing oraz unboxing. Jak wiemy z poprzedniego wpisu struktury przechowywane są na stosie a klasy na stercie. Boxing to niż innego jak wrapping struktury (lub jakiekolwiek innego typu wartościowego) w obiekt przechowywany na stercie. Na przykład:

int value=0;
object boxedValue=value; // boxing

Zmienna value przechowywana jest na stosie, z kolei boxedValue na stercie (pamiętajmy o nagłówku oraz GC). Należy zwrócić szczególną uwagę na boxing gdy wykorzystujemy struktury, ponieważ nieumiejętny sposób użycia może spowodować znaczny spadek wydajności zamiast wzrost. Analogicznie unboxing to proces odwrotny:

int value=0;
object boxedValue=value; // boxing
value= (int)boxedValue;//unboxing

Warto zwrócić uwagę, że boxing jest zwykle niejawny a unboxing jawny. Podczas boxingu, wymaga jest alokacja dodatkowej pamięci. Przyjrzyjmy się więc jak wygląda nasza pamięć przed i po:

image

Struktura w pamięci znacząco się zmienia i dzieję się to kosztem wydajności. Aby udowodnić, że podczas boxing’u alokowana jest nowa pamięć rozważmy:

int i = 1;
object o = i;
i = 2;  

Po skompilowaniu okaże się, że i ma wartość 2 a o 1 – to całkowicie oddzielne zmienne. Nieprawidłowy unboxing wywołuje wyjątek InvalidCastException:

int i = 1;
object o = i;
try
{
 double doubleValue = (double) o;
}
catch (System.InvalidCastException e)
{

}

Podczas unboxingu można zatem wyróżnić dwie czynności:

  1. Sprawdzenie czy owinięty typ jest taki sam jak ten na który rzutujemy. Jeśli typy nie zgadzają się, wyrzucany jest wyjątek InvalidCastException.
  2. Alokacja nowej pamięci na stosie oraz z kopiowanie wartości.

Z przedstawionych powyżej powodów, używanie kolekcji ArrayList jest bardzo złym podejściem. Lepszym rozwiązaniem jest wprowadzanie typów generycznych. Stosownie do MSDN, boxing jest 20 razy wolniejszy a unboxing 4 razy wolniejszy niż tradycyjne rozwiązania niewymagające tych mechanizmów.

2 thoughts on “Boxing i unboxing.”

Leave a Reply

Your email address will not be published.