装箱:
就是将一个值类型显式或者隐式的转化为一个object类型,或者是转化成一个被该值类型应用的接口类型,将一个值类型装箱,就创建了一个object实例,并且将这个值赋值给了object,object对象的数据位于堆中,在栈上有对该对象的引用,而被装箱的类型的值是被作为一个复制的文件赋给对象的,所谓拆箱,就是装箱操作的反操作,复制堆中的对象至栈中,并且返回其值。
拆箱:就是装箱操作的反操作,复制堆中的对象至栈中,并且返回其值。
性能损失:
相比于简单的赋值操作,装箱和拆箱需要进行大量的计算,对值类型进行装箱时,需要分配并构造一个全新的对象。
为了解决装箱与拆箱带来的性能损失问题,微软公司在.NET中提供了泛型。
看下例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Unbox
{
public static Stopwatch sw = new Stopwatch();
public static void RunUnbox()
{
int count;
ArrayList MyArrayList = new ArrayList();
sw.Start();
for (int i = 0; i < 5; i++)
{
MyArrayList.Clear();
for (count = 0; count < 5000000; count++)
{
MyArrayList.Add(count); //装箱
}
int j;
for (count = 0; count < 5000000; count++)
{
j = (int)MyArrayList[count];//拆箱
}
}
Console.WriteLine("使用装箱和拆箱共花时间:{0}", sw.ElapsedMilliseconds);
}
public static void RunNoBox()
{
int count;
List<int> MyTList = new List<int>();
sw.Reset();
sw.Start();
for (int i = 0; i < 5; i++)
{
MyTList.Clear();
for (count = 0; count < 5000000; count++)
{
MyTList.Add(count);
}
int j;
for (count = 0; count < 5000000; count++)
{
j = MyTList[count];
}
}
Console.WriteLine("使用泛型共花时间:{0}", sw.ElapsedMilliseconds);
}
}
class Test
{
static void Main(string[] args)
{
Unbox.RunUnbox();
Unbox.RunNoBox();
Console.ReadLine();
}
}
}
输出结果: