Home > .Net Fundations, Computer Science > Boxing and Unboxing (A key reason to use Generic)

Boxing and Unboxing (A key reason to use Generic)

This article is a discussion about boxing and unboxing in .Net and also the ways to overcome it.

This term is mostly used when we want to convert value types to reference types or vice versa. We really should care about it in development of critical systems, web applications with high traffic or using classes or methods with frequent use.

Boxing: This is the process of converting the value of a value type variable to a reference type variable.

Assume that you want to store a user-defined type (struct) into an ArrayList (As you know user-defined/struct types are value type). Now let’s know what is stored in this ArrayList?

If you take a look at the Add() method of ArrayList, it has only one overload for this method which is Add(Object object) [and Object is a reference type]. It is good news due to the possibility of storing totally different types into each index of an ArrayList. However, it has some bad news too because it needs to convert your value type variable to a reference type variable. It means that it needs a boxing to fulfill this need.

struct TypeA

{

public int VarA;

public int VarB;

public TypeA(int VarA, int VarB)

{

this.VarA = VarA;

this.VarB = VarB;

}

}

public void TestBoxingAndUnBoxing()

{

TypeA typeA = new TypeA(10, 20);

System.Collections.ArrayList arrList = new System.Collections.ArrayList();

//Boxing occures here 

arrList.Add(typeA);

}

What Happens when a boxing occurs:

1- Because value-typed variables are stored in stack, a new memory cell in heap must be allocated to store this object. Reference types use heap (dynamic memory space) to be stored.

2- The value type’s bits are copied from stack to their new location in heap.

3- The new address is returned to be stored in ArrayList. So we now have a reference type instead of a value type.

Therefore, boxing can be very expensive and sometimes harmful.

Unboxing: is, of course, exactly opposite to boxing, it is the time when a reference type is converted to a value type.

After storing value types into ArrayList, they are wanted to be used somewhere. In other words, you should convert them to their original type in order to use them.

typeA = (TypeA)arrList[0];

System.Console.Write(typeA.VarB.ToString());

What happens in unboxing?

1- It Checks whether it is null or not, then it checks whether the specified type is convertible or not. If both of the above conditions fail it returns an exception.

2- The reference of the object inside the ArrayList is returned. Then bits are copied into the value typed variable.

It has some penalties again. To overcome this problem .Net suggests using Generics when time is totally eminent (But it is a better to consider it always).

Generics is out of scope of this article; however, I describe it briefly in a sample code to show its power and its immense difference compared with objects.

Generics classes/methods are similar to type-less ones but they are not. You can specify their types before compile time when you are coding. For example for classes their types must be specified during their instantiation. Therefore, it gives you the flexibility to have different types in each instance of a class.

Code below is a comparison between a Generic class and an Object one.

//T and U are generic types. It means that you can specify their types in class instantiation. So

class GenericClass
{
public T t;
public U u;

 public GenericClass(T t, U u)
{
this.t = t;
this.u = u;
}
}

//An object class that may cause boxing and unboxing during run-time
class ObjectClass
{
public object t;
public object u;

 

 public ObjectClass(object t, object u)
{
this.t = t;
this.u = u;
}
}

Now I want to show you the time it takes to work with each one of them for ten million iterations.

protected void Page_Load(object sender, EventArgs e)
{
DateTime dt1 = DateTime.Now;
ObjectClass ObjClass;
for (int i = 0; i < 10000000; i++)
{
ObjClass = new ObjectClass(10, "Peace");
}
DateTime dt2 = DateTime.Now;

TimeSpan tsDef = dt2.Subtract(dt1);
Response.Write("Object: " + tsDef.TotalMilliseconds.ToString() + "
");

 dt1 = DateTime.Now;
GenericClass GenClass;
for (int i = 0; i < 10000000; i++)
{
GenClass = new GenericClass(10, "Peace");
}
dt2 = DateTime.Now;
tsDef = dt2.Subtract(dt1);
Response.Write("Generic: " + tsDef.TotalMilliseconds.ToString());
}
Boxing and Unboxing

Fig 1, the result of comparision

The result clearly shows this difference. (Of course, you get different results each time you run the program but the ratio remains almost the same)

As you see, it is near to two times faster by using the Generic types.

Reference: Jeffrey Richter, MSPress: MCTS Self-Paced Training Kit (Exam 70-536)

Advertisements
  1. DJ
    February 7, 2013 at 2:28 pm

    Thank you for explaining this…very good article.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: